Skip to main content

Complete payment flow

This guide walks through the full payment lifecycle in the Advanced Flow — from checking eligible payment methods and displaying saved cards, to collecting card details, creating the payment, and optionally registering a card for future use.

Flow overview​

Step 1 — Check eligible payment methods​

Before rendering the checkout, call the eligibility endpoint to determine which payment methods are available for the order. This prevents presenting options that cannot be fulfilled by the PSP.

Required fields: entity_id, amount, currency, order. The customer object is optional but recommended — it enables PSP-level eligibility checks based on customer profile.

curl -X POST 'https://api.purse-sandbox.com/payment/v2/eligible-solutions' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--data-raw '{
"entity_id": "${ENTITY_ID}",
"amount": 4999,
"currency": "EUR",
"customer": {
"reference": "customer-123",
"type": "PERSON",
"email": "[email protected]",
"ip_address": "203.0.113.195",
"locale": "fr-FR"
},
"order": {
"reference": "order-456",
"net_amount": 4999,
"tax_amount": 833,
"billing_address": {
"first_name": "Emily",
"last_name": "Parker",
"address_lines": ["67 Rue de Luxembourg"],
"city": "Lille",
"postal_code": "59777",
"country_code": "FR"
}
}
}'
API Endpoint
  • Endpoint: /payment/v2/eligible-solutions
  • Method: POST
  • API Reference

Response:

{
"amount": 4999,
"currency": "EUR",
"eligible_solutions": [
{
"partner": "dalenys",
"method": "creditcard",
"supported_brands": ["CARTE_BANCAIRE", "VISA", "MASTERCARD"]
},
{
"partner": "oney",
"method": "cb3x",
"additional_data": {
"opc": "WB123",
"is_free": "true",
"customer_display_label": "Payez en 3x sans frais"
}
},
{ "partner": "paypal", "method": "wallet" }
]
}

Use eligible_solutions to conditionally render payment method buttons — for example, show a "Pay in 3x" option only when oney/cb3x is present.

allow_future_usage

If the order is the first of a recurring payment series, pass "allow_future_usage": true. This signals to the PSP that the card may be charged again in the future.

Step 2 — Display saved cards​

If the customer has an account, fetch their active tokens directly from the Wallet API v3 — no session required.

curl -X GET \
'https://api.purse-sandbox.com/wallet/v3/merchants/${ENTITY_ID}/customers/${CUSTOMER_REFERENCE}/tokens?status=ACTIVE' \
--header "Authorization: Bearer ${ACCESS_TOKEN}"
API Endpoint
  • Endpoint: /wallet/v3/merchants/{merchant_id}/customers/{customer_reference}/tokens
  • Method: GET
  • API Reference

Response:

{
"tokens": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "ACTIVE",
"description": {
"brand_name": "VISA",
"display_token": "****4242",
"holder_name": "Emily Parker"
},
"expiration_date": "2027-01-01T00:00:00Z",
"favorite": true
}
],
"total_elements": 1
}

Render a button per token using description.display_token and description.brand_name. When the customer selects a token, initialize a CVV-only SecureFields form — see Token Payment.

Step 3 — Display the card form​

When the customer has no saved cards or chooses to enter a new card, render the full SecureFields form:

import { loadSecureFields } from '@purse-eu/web-sdk';

// supported_brands of the creditcard solution returned by the eligibility call in Step 1
const cardSolution = eligible_solutions.find(s => s.method === 'creditcard');

const sf = await loadSecureFields('sandbox');
const secureForm = await sf.initSecureFields({
tenantId: '${VAULT_TENANT_ID}',
config: {
brands: cardSolution?.supported_brands ?? ['VISA', 'MASTERCARD', 'CARTE_BANCAIRE'],
brandSelector: true,
fields: {
cardNumber: { target: 'pan-placeholder', placeholder: '1234 5678 9012 3456' },
cvv: { target: 'cvv-placeholder', placeholder: '123' },
expDate: { target: 'exp-placeholder', placeholder: 'MM/YY' },
holderName: { target: 'holder-placeholder', placeholder: 'John Doe' },
},
},
});

await secureForm.render();

const result = await secureForm.submit({ saveToken: false });
// Send result.vault_form_token to your backend

See Getting Started for the complete SecureFields initialization and event handling.

Step 4 — Create a payment​

With a new card​

Your backend receives the vault_form_token from the frontend and calls the Payment API:

curl -X POST 'https://api.purse-sandbox.com/payment/v2/payments' \
--header 'Content-Type: application/json' \
--header "x-api-key: ${API_KEY}" \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--data-raw '{
"entity_id": "${ENTITY_ID}",
"amount": 4999,
"currency": "EUR",
"order": {
"reference": "order-456"
},
"split": [
{
"vault_form_token": "${VAULT_FORM_TOKEN}",
"three_ds_authentication_options": {
"challenge_indicator": "NO_CHALLENGE_REQUESTED"
}
}
],
"browser": {
"user_agent": "Mozilla/5.0...",
"accept_header": "text/html",
"color_depth": 32,
"screen_height": 1200,
"screen_width": 1920,
"locale": "fr-FR",
"utc_time_zone": 60
}
}'

With a saved token​

After the customer submits the CVV-only form, the frontend sends both vault_form_token and wallet_token_id to the backend:

curl -X POST 'https://api.purse-sandbox.com/payment/v2/payments' \
--header 'Content-Type: application/json' \
--header "x-api-key: ${API_KEY}" \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--data-raw '{
"entity_id": "${ENTITY_ID}",
"amount": 4999,
"currency": "EUR",
"split": [
{
"vault_form_token": "${CVV_VAULT_FORM_TOKEN}",
"wallet_token": "${WALLET_TOKEN_ID}"
}
],
"browser": {
"user_agent": "Mozilla/5.0...",
"accept_header": "text/html",
"color_depth": 32,
"screen_height": 1200,
"screen_width": 1920,
"locale": "fr-FR",
"utc_time_zone": 60
}
}'
API Endpoint

Step 5 — Register a token​

Automatically during payment​

Pass save_token: true in the split item. After a successful payment, the card is automatically added to the customer's wallet.

"split": [
{
"vault_form_token": "${VAULT_FORM_TOKEN}",
"save_token": true
}
]

The payment response includes token_saved: true and the wallet_token ID when registration succeeds.

User consent

Always obtain explicit customer consent before saving a card. Use a checkbox in your checkout UI and only pass save_token: true when the customer has opted in.

Manually via the Wallet API​

To register a card independently of a payment — for example, in an account management screen — call the Wallet API v3 directly:

curl -X POST \
'https://api.purse-sandbox.com/wallet/v3/merchants/${ENTITY_ID}/customers/${CUSTOMER_REFERENCE}/tokens' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--data-raw '{
"token": "${VAULT_CARD_TOKEN}",
"expiration_date": "2027-01-01T00:00:00Z",
"description": {
"brand_name": "VISA",
"display_token": "****4242",
"holder_name": "Emily Parker"
},
"scope": {
"partner": "dalenys",
"method": "creditcard",
"origin": "purse"
}
}'
API Endpoint
  • Endpoint: /wallet/v3/merchants/{merchant_id}/customers/{customer_reference}/tokens
  • Method: POST
  • API Reference

The response returns a TokenProjectionV3 with the assigned id, which you can store to reference the token in future payments.

Next steps​