# Save a card during payment

{% tabs %}
{% tab title="Prebuilt Checkout page" %}
Save customer's card details on Checkout page, can help customers to pay more quickly in their next payments.

### 1. Create a Customer&#x20;

Create a corresponding Customer object for your customer in MoneyCollect.

```java
// Use your private key
MoneyCollect.apiKey = "test_pr_NWZsa******";

CustomerCreateParams customerCreateParams =
            CustomerCreateParams.builder()
                    .setEmail("test@moneycollect.com").build();
Customer customer = Customer.create(customerCreateParams);
```

### 2. Create Checkout Session

When creating the Checkout Session, you can specify the `customer`parameter to automatically attach the created payment method to an existing customer.

```java
// Use your private key
MoneyCollect.apiKey = "test_pr_NWZsa******";

SessionCreateParams params =
          SessionCreateParams.builder()
                    .setReturnUrl("http://localhost:4242/success.html")
                    .setCancelUrl("http://localhost:4242/cancel.html")
                    .setNotifyUrl("http://localhost:4242/success.html")
                    .setAmountTotal(18*100L)
                    .setCurrency("USD")
                    .setOrderNo("C"+System.currentTimeMillis())
                    .setWebsite("https://www.localhost.com")
                    .setBillingDetails(getBillingDetails())
                    .setCustomer(customer.getId())
                    .setStatementDescriptor("Mc122").build();
Session session = Session.create(params); 
```

### 3. Customer selects "save this card" during payment

![](https://3906929740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQyT5pndc80PGeNrMulEU%2Fuploads%2FZ2NIq8GLXghHg6aGSDB6%2FyReXXAc6U3Q.png?alt=media\&token=42fc0f13-309f-4a08-9b06-5b810b3dab10)

1. Select "Save this card for future purchase" on the Checkout page.
2. Click "Pay".
3. After pay will save the card details to customer.

### 4. Customer selects the saved card to make payment&#x20;

![](https://3906929740-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQyT5pndc80PGeNrMulEU%2Fuploads%2F9zinpV860MVXCPqvWCqQ%2F8DNrwf9lR5A.png?alt=media\&token=84af7760-6eaf-47d3-aa79-ec05f5085420)
{% endtab %}

{% tab title="Custom payment flow" %}
Use the Payment API to save payment details from a purchase. There are several use cases:

* After the customer pays an order,store the payment details for future purchases.
* Initiate the first payment of a series of recurring payments.
* Charge reserved funds and store the details to charge the full amount later

### 1. Set up MoneyCollect

Firstly, make sure that you have set up an account name on the MoneyCollect Dashboard.

### 2. Create a customer before set up

To set up a payment method for future payments, you must attach it to a Customer. Create a `customer` object in MoneyCollect when your customer creates an account on your website. It is also possible to create a `customer` object in MoneyCollect before the customer is ready to pay. Customer objects allow for reusing payment methods and tracking across multiple payments.

```java
// Use your private key
MoneyCollect.apiKey = "test_pr_NWZsa******";

CustomerCreateParams customerCreateParams =
            CustomerCreateParams.builder()
                    .setEmail("test@moneycollect.com").build();
Customer customer = Customer.create(customerCreateParams);
```

### 3. Create Payment&#x20;

To create a payment, specify the amount, currency, orderNo and customer.

```java
// Use your private key
MoneyCollect.apiKey = "test_pr_NWZsa******";

PaymentCreateParams params =
                    PaymentCreateParams.builder()
                           .setAmount(14*100L)
                           .setCurrency("USD")
                           .setOrderNo("MC"+System.currentTimeMillis())                       
                           .setStatementDescriptor("McDescriptor")
                           .setCustomerId(customer.getId()).build();//

Payment payment =  Payment.create(params);
return JSONObject.toJSONString(new CreatePaymentResponse(payment.getId(),payment.getClientSecret()));
```

After the Payment is created, only need to return the `clientSecret` in the returned result to the payment page. It is used to confirm the payment and update the card information on the client.

### 4. Collect card details

After the payment is created on the server and the `clientSecret` is transferred to the browser, you’re ready to collect Elements of the payment details on the client by using MoneyCollect.js. Elements is a set of prebuilt UI components that used to collect and verify card numbers, CVVs, and dates of expiration.

Include the moneycollect.js script on your checkout page by adding it to the head of your HTML file. Always load moneycollect.js directly from js.moneycollect.com to remain PCI compliant.

**1. Set up MoneyCollect Elements**

```javascript
async function setupElements()  {
    moneyCollect = MoneycollectPay(apikey);
    let params = {
        formId: 'payment-form', // payment-form id
        frameId: 'PrivateFrame', //IframeId
        mode: "pro",
        customerId: "",
        needCardList: true,
        autoValidate: true,
        layout: {
            pageMode: "inner", // Style mode of the page   inner | block
            style: {
                frameMaxHeight: "50", //  The max height of iframe
                input: {
                    FontSize: "", // Collect the size of the font
                    FontFamily: "",  // Specify a prioritized list of one or more font family names 
                    FontWeight: "",  // Collect the weight (or boldness) of the font
                    Color: "", // Collect the foreground color value of an element's text
                    ContainerBorder: "",  //Collect the name of the font
                    ContainerBg: "",  // Collect the weight (or boldness) of the font
                    ContainerSh: "" //Collect the color of the font
                }
            }
        }
    }
    moneyCollect.elementInit("payment_steps", params);
}
```

**2. Add Elements to your page**

```html
<!-- Display a payment form -->
<form id="payment-form">
    <div id="card-element" class="ab-element">
        <!--MoneyCollect.js injects the Payment Element-->
    </div>
    <div class="sr-field-error" id="card-errors" role="alert"></div>
    <button id="submit">
        <div class="spinner hidden" id="spinner"></div>
        <span id="button-text">Pay now</span>
    </button>
    <div id="payment-message" class="hidden" style="color:#ff0000"></div>
</form>
```

#### **3. Set billing details**

Set billingDetails before submitting payment to MoneyCollect

```javascript
let paymentMethodsData = {
    billingDetails: {
        address: {
            city: "Hong Kong",
            country: "CN",
            line1: "193 Prince Edward Road",
            line2: "",
            postalCode: "421455",
            state: "Hong Kong"
        },
        email: "test007@mail.com",
        firstName: "smith",
        lastName: "diana",
        phone: "19112454541"
    }
}
```

### 5. Submit the payment to MoneyCollect&#x20;

```javascript
moneyCollect.confirmPayment({
        paymentMethod: paymentMethodsData,
        autoJump: false,
        payment_id: paymentId,
        clientSecret: clientSecret,
        confirmDetail: {
          setupFutureUsage:"on"
        }
    }).then((result) => {
        console.log(result);
        if(result.data.code === "success"){
            orderComplete(result.data.data);
        } else {
            console.log(result.data.msg);
            showMessage(result.data.msg);
        }
    });
 
```

| Note                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p><code>setupFutureUsage</code>:<br>It is used to set whether the card information can be used for payments in the future.<br>Set <code>setupFutureUsage</code> to 'on' && <code>customer</code> is provided when payment is created, the card information will be automatically attached to the <code>customer</code> when the Payment is confirmed.<br>You can also set this parameter when creating a Payment on the <code>server-side</code>.</p> |

> Confirm Payment may take several seconds to complete. During that time, disable your form from being resubmitted.If the customer must perform additional steps to complete the payment, such as authentication, moneycollect.js guides them through that process.

when a payment is successful, the returned status of `Payment` is `succeeded` . when a payment fails, you can check the returned error to determine the reason.

If the payment succeeded, you can use the stored `customerId`,`paymentMethod` from the responsive payment information to collect payments from your customer in the future without prompting them for their payment details again.

### 6. Charge using saved payment method

List all payment methods associated with your customer, and pick one of payment methods to charge.

```java
// Use your private key
MoneyCollect.apiKey = "test_pr_NWZsa******";

PaymentMethodListParams listParams =
     PaymentMethodListParams.builder()
            .setCustomerId(customer.getId())
            .build();
PaymentMethodCollection lst =  PaymentMethod.list(listParams);
List<PaymentMethod> paymentMethodlist = lst.getData();
```

* Use `customer` and `paymentMethod` you pick.
* Set up all related information of payments.
* Set`confirm` to "true": The payment will be automatically charged when the payment is created.
* Set`paymentMethod`to the ID of the PaymentMethod.
* Set`customerId`to the ID of the Customer.

```java
// Use your private key
MoneyCollect.apiKey = "test_pr_NWZsa******";

PaymentCreateParams params =
                    PaymentCreateParams.builder()
                            .setAmount(14 * 100L)
                            .setCurrency("USD")
                            .setOrderNo("MC"+System.currentTimeMillis())
                            .setIp("103.48.140.12")
                            .setPaymentMethod(paymentMethod.getId())
                            .setCustomerId(customer.getId())
                            .setConfirm(true) 
                            .build();

Payment payment =  Payment.create(params); 
return JSONObject.toJSONString(payment);
```

There are two scenarios of charge failure: request failure and payment failure.

* Request failure：When`code` is not `success`, request fails, `msg`describes the reason for charge failure.

```json
{
  "code": "api_amount_is_empty",
  "msg": "Amount cannot be empty.",
  "data": null
}
```

* Payment failure：`status`is failed,`errorCode`and`errorMessage`describe the reason for charge failure.

```json
{
  "code": "success",
  "msg": "success",
  "data": {
    ....
    "riskInfo": {
      "riskScore": 0,
      "riskMessage": "risk_pass"
    },
    "status": "failed",
    "errorCode": "insufficient_funds",
    "errorMessage": "insufficient_funds."
  }
}
```

> For more Payment `status`, please check the description of Payment API's status.

### 7. Testing

There are several test cards you can use to make sure this integration is ready for production. Use them with any CVC, postal code, and future expiration date.

| NUMBER              | Brand            | DESCRIPTION                                     |
| ------------------- | ---------------- | ----------------------------------------------- |
| 4242 4242 4242 4242 | Visa             | Succeeds and immediately processes the payment. |
| 3566 0020 2036 0505 | JCB              | Succeeds and immediately processes the payment. |
| 6011 1111 1111 1117 | Discover         | Succeeds and immediately processes the payment. |
| 3782 8224 6310 0052 | American Express | Succeeds and immediately processes the payment. |
| 5555 5555 5555 4444 | Mastercard       | Succeeds and immediately processes the payment. |
| 4000 0000 0000 0077 | Visa             | Always fails with a decline code of `declined`. |
| {% endtab %}        |                  |                                                 |
| {% endtabs %}       |                  |                                                 |
