Saving a payment instrument for future use
In this guide, you will learn how to save a payment instrument to a specific customer and use it when making a payment. This approach gives you the flexibility to avoid managing the payment card data for your customers on your servers and eliminates the necessity to have PCI DSS certification.
You will go through the following steps:
- Create a customer
- Tokenize a card for a customer
- Create a checkout
- Complete a checkout with a tokenized card
When you complete these steps, you will have saved a payment instrument for a customer of yours and will have made a payment with the token associated with that payment instrument.
Before you begin
Here are the things that you need in order to complete the steps in this guide:
- You have a merchant account with SumUp and have already filled in your account details.
- For a test account reach out to our support team through this contact form.
- You have registered your client application with SumUp.
- You have a valid access token obtained via the Authorization code flow.
- The restricted
payment_instruments
scope is enabled for your client application. If it isn't enabled, contact us and request it.
Steps
1. Create a customer
To create a new customer resource, make a POST request to the https://api.sumup.com/v0.1/customers
endpoint.
The request body should be a JSON object that contains a unique identifier for your customer in the customer_id
attribute. Optionally, you can include additional personal details for your customer, such as name, contact details, and a postal address. For more information about the request, see the API reference.
Following is a sample request for creating a new customer resource:
curl -X POST \
https://api.sumup.com/v0.1/customers \
-H 'Authorization: Bearer $SUMUP_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"customer_id": "DC000101",
"personal_details": {
"first_name": "Boaty",
"last_name": "McBoatface",
"phone": "+497453505382",
"address": {
"line1": "See Strasse 40",
"country": "DE",
"postal_code": "12345",
"city": "Frankfurt"
}
}
}'
ctx := context.Background()
client := sumup.NewClient().WithAuth(os.Getenv("SUMUP_API_KEY"))
ptr := func(s string) *string {
return &s
}
customer, err := client.Customers.Create(ctx, sumup.CreateCustomerBody{
CustomerId: "DC000101",
PersonalDetails: &sumup.PersonalDetails{
Address: &sumup.Address{
City: ptr("Frankfurt"),
Country: "DE",
Line1: ptr("See Strasse 40"),
PostalCode: ptr("12345"),
},
FirstName: ptr("Boaty"),
LastName: ptr("McBoatface"),
Phone: ptr("+497453505382"),
},
})
$customersService = $sumup->getCustomerService();
$response = $customersService->create(
'DC000101',
[
'first_name' => 'Dominik',
'last_name' => 'Biermann',
'phone' => '+497453505382'
],
[
'line1' => 'Ollenhauer Str. 60',
'line2' => 'Wohnungsnummer 3',
'country' => 'Germany',
'postal_code' => '70437',
'city' => 'Stuttgart'
]
);
The response contains a JSON body with the details of the created customer resource. As you will notice, there isn't an internal identifier for the customer resource - the primary identifier of the resource is the one you provide in the request. You can use this identifier to perform all necessary operations with this resource.
{
"customer_id": "DC000101",
"personal_details": {
"first_name": "Dominik",
"last_name": "Biermann",
"phone": "+497453505382",
"address": {
"city": "Stuttgart",
"country": "Germany",
"line1": "Ollenhauer Str. 60",
"line2": "Wohnungsnummer 3",
"postal_code": "70437"
}
}
}
2. Tokenize a payment instrument for a customer
To tokenize a payment instrument and save it for an existing customer, make a POST request to the https://api.sumup.com/v0.1/customers/{customer_id}/payment-instruments
endpoint, where the value of the {customer_id}
path parameter is the unique identifier of the customer resource.
The request body should be a JSON object with the payment instrument type (card
) and the payment card details. For more information about the request body parameters, see the API Reference.
Following is a sample request for tokenizing a card for the customer from Step 1:
curl -X POST \
https://api.sumup.com/v0.1/customers/DC000101/payment-instruments \
-H 'Authorization: Basic $SUMUP_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"type": "card",
"card": {
"name": "Boaty McBoatface",
"number": "4200000000000042",
"expiry_month": "12",
"expiry_year": "23",
"cvv": "123"
}
}'
ctx := context.Background()
client := sumup.NewClient().WithAuth(os.Getenv("SUMUP_API_KEY"))
paymentInstrument, err := client.Customers.CreatePaymentInstrument(ctx, "DC000101", sumup.CreatePaymentInstrumentBody{
Card: sumup.Card{
Cvv: "123",
ExpiryMonth: "12",
ExpiryYear: "23",
Name: "Boaty McBoatface",
Number: "4200000000000042",
},
Type: sumup.CreatePaymentInstrumentBodyTypeCard,
})
The response contains a JSON body with the details of the tokenized card resource. The token
attribute serves as the unique identifier of the resource. You need to store it and use it to perform all necessary operations with the saved card, such as processing payments for the saved customer in Step 4.
{
"token": "0e18b211-b2b6-4ca0-975d-a7768320432d",
"active": true,
"type": "card",
"card": {
"last_4_digits": "3995",
"type": "VISA"
}
}
3. Create a checkout
To create a new checkout resource, make a POST request to the https://api.sumup.com/v0.1/checkouts
endpoint.
The request body should be a JSON object with the same minimum details as the checkout you created in the guide for making a payment with a card entered by a customer .
Following is a sample request for creating a new checkout resource:
curl -X POST \
https://api.sumup.com/v0.1/checkouts \
-H 'Authorization: Bearer $SUMUP_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"checkout_reference": "CO746453",
"amount": 10,
"currency": "EUR",
"pay_to_email": "[email protected]",
"description": "Sample one-time payment"
}'
ctx := context.Background()
client := sumup.NewClient().WithAuth(os.Getenv("SUMUP_API_KEY"))
checkout, err := client.Checkouts.Create(ctx, sumup.CreateCheckoutBody{
Amount: 19,
CheckoutReference: "CO746453",
Currency: "EUR",
MerchantCode: "MK0001",
})
$checkoutsService = $sumup->getCheckoutService();
$response = $checkoutsService->create(42.24, 'EUR', 'CO287866', '[email protected]', 'Sample payment for a saved customer');
$checkoutId = $response->getBody()->id;
Again, the response contains a JSON body with the details of the created resource in which the resource identifier is returned in the id
attribute (4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2
in the sample response below) and the status
attribute shows that the payment for this resource is pending and will be processed when you complete the checkout with the payment instrument details.
{
"checkout_reference": "CO287866",
"amount": 42.24,
"currency": "EUR",
"pay_to_email": "[email protected]",
"description": "Sample payment for a saved customer",
"id": "4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2",
"status": "PENDING",
"date": "2018-09-28T13:47:01.832Z",
"transactions": []
}
4. Complete a checkout with a tokenized card
To complete the checkout and trigger the payment with a tokenized card, make a PUT request to the https://api.sumup.com/v0.1/checkouts/{id}
endpoint, where the value of the {id}
path parameter is the identifier of the checkout resource.
Similarly to the checkout you completed in the guide for making a payment with a card entered by a customer, the request body should be a JSON object with the payment type (card
) but instead of including the payment card details, you need to specify the token of the payment card from Step 2 and the identifier of the customer for whom the card is saved from Step 1. For more information about the request, see the API Reference.
Following is a sample request for completing the checkout from Step 3:
curl -X PUT \
https://api.sumup.com/v0.1/checkouts/4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2 \
-H 'Authorization: Bearer $SUMUP_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"payment_type": "card",
"token": "0e18b211-b2b6-4ca0-975d-a7768320432d",
"customer_id": "DC000101"
}'
ctx := context.Background()
client := sumup.NewClient().WithAuth(os.Getenv("SUMUP_API_KEY"))
ptr := func(v string) *string {
return &v
}
checkoutSuccess, err := client.Checkouts.Process(ctx, *checkout.Id, sumup.ProcessCheckoutBody{
PaymentType: sumup.ProcessCheckoutBodyPaymentTypeCard,
Token: ptr("0e18b211-b2b6-4ca0-975d-a7768320432d"),
CustomerId: "DC000101",
})
$checkoutsService = $sumup->getCheckoutService();
$response = $checkoutsService->pay('4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2', 'DC000101', '0e18b211-b2b6-4ca0-975d-a7768320432d');
$transactionId = $response->getBody()->transaction_id;
The response contains a JSON body with the details of the processed checkout resource in which the attributes related to the payment outcome are populated:
{
"checkout_reference": "CO287866",
"amount": 42.24,
"currency": "EUR",
"pay_to_email": "[email protected]",
"description": "Sample payment for a saved customer",
"id": "4ebc2ed7-bb8c-4d4d-a110-08fd31301bf2",
"status": "PAID",
"date": "2018-09-28T13:57:09.038Z",
"transaction_code": "TDQ49H22AS",
"transaction_id": "664200af-2b62-4142-9c73-a2a505310d78",
"transactions": [
{
"id": "664200af-2b62-4142-9c73-a2a505310d78",
"transaction_code": "TDQ49H22AS",
"merchant_code": "ME7RMQN3",
"amount": 42.24,
"vat_amount": 0,
"tip_amount": 0,
"currency": "EUR",
"timestamp": "2018-09-28T13:58:05.655Z",
"status": "SUCCESSFUL",
"payment_type": "RECURRING",
"entry_mode": "CUSTOMER_ENTRY",
"installments_count": 1,
"auth_code": "073660",
"internal_id": 24118510
}
]
}
Result
You have made a payment with a tokenized card associated with a specific customer saved for a merchant user's account. If the payment is successful, the funds will be transferred to the merchant user according to the configured account settings.