Skip to main content

Create a payment

Once your frontend has submitted the SecureFields form and your backend has received the vault_form_token, call the Payment API to create the payment.

Request

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",
"net_amount": 4999,
"tax_amount": 833
},
"split": [
{
"vault_form_token": "${VAULT_FORM_TOKEN}",
"three_ds_authentication_options": {
"challenge_indicator": "NO_CHALLENGE_REQUESTED"
}
}
],
"browser": {
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"accept_header": "text/html",
"color_depth": 32,
"java_enabled": false,
"javascript_enabled": true,
"locale": "fr-FR",
"screen_height": 1080,
"screen_width": 1920,
"utc_time_zone": 60
}
}'
API Endpoint

Key request fields

FieldRequiredDescription
entity_idYesYour merchant entity UUID
amountYesAmount in currency minor units (e.g. 4999 = 49.99 EUR)
currencyYesISO 4217 code
split[].vault_form_tokenYesToken returned by the SecureFields SDK submit
split[].save_tokenNotrue to save the card for future payments
browserYesBrowser fingerprint for 3DS compliance

3DS browser parameters

The browser object is mandatory for 3DS compliance. Collect these values client-side and send them to your backend with the vault_form_token.

ParameterTypeDescription
user_agentstringBrowser user agent string
accept_headerstringBrowser Accept header
color_depthintegerScreen color depth (window.screen.colorDepth)
java_enabledbooleanJava support (navigator.javaEnabled())
javascript_enabledbooleanAlways true if JS is running
localestringBrowser locale (navigator.language)
screen_heightintegerScreen height in pixels
screen_widthintegerScreen width in pixels
utc_time_zoneintegerUTC offset in minutes (new Date().getTimezoneOffset() * -1)
referrerstringPage referrer URL (optional)

Collect these values on the client side before submitting the form:

const browserData = {
user_agent: navigator.userAgent,
accept_header: 'text/html',
color_depth: window.screen.colorDepth,
java_enabled: navigator.javaEnabled?.() ?? false,
javascript_enabled: true,
locale: navigator.language,
screen_height: window.screen.height,
screen_width: window.screen.width,
utc_time_zone: new Date().getTimezoneOffset() * -1,
};

3DS challenge indicator

Control 3DS challenge behavior via three_ds_authentication_options.challenge_indicator in the split item:

ValueDescription
NO_CHALLENGE_REQUESTEDRequest frictionless flow (PSP may still trigger challenge)
CHALLENGE_REQUESTEDRequest a challenge — use for high-risk transactions
CHALLENGE_REQUESTED_AS_MANDATEMandate challenge — required for certain regulatory contexts

Response

A successful call returns a payment object with a redirect_url for 3DS:

{
"id": "pay_abc123",
"status": "PENDING",
"amount": 4999,
"currency": "EUR",
"redirect_url": "https://3ds.psp.com/authenticate?token=xyz"
}

Redirect the customer to redirect_url to complete 3DS authentication. After authentication, the PSP redirects back to the shopper_redirection_url you provided.

Final status via webhook

Do not rely on the redirect callback for the final payment status. Subscribe to the payment.updated webhook event — see Webhooks for setup.

Next steps