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
}
}'
- Endpoint:
/payment/v2/payments - Method:
POST - API Reference
Key request fields
| Field | Required | Description |
|---|---|---|
entity_id | Yes | Your merchant entity UUID |
amount | Yes | Amount in currency minor units (e.g. 4999 = 49.99 EUR) |
currency | Yes | ISO 4217 code |
split[].vault_form_token | Yes | Token returned by the SecureFields SDK submit |
split[].save_token | No | true to save the card for future payments |
browser | Yes | Browser 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.
| Parameter | Type | Description |
|---|---|---|
user_agent | string | Browser user agent string |
accept_header | string | Browser Accept header |
color_depth | integer | Screen color depth (window.screen.colorDepth) |
java_enabled | boolean | Java support (navigator.javaEnabled()) |
javascript_enabled | boolean | Always true if JS is running |
locale | string | Browser locale (navigator.language) |
screen_height | integer | Screen height in pixels |
screen_width | integer | Screen width in pixels |
utc_time_zone | integer | UTC offset in minutes (new Date().getTimezoneOffset() * -1) |
referrer | string | Page 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:
| Value | Description |
|---|---|
NO_CHALLENGE_REQUESTED | Request frictionless flow (PSP may still trigger challenge) |
CHALLENGE_REQUESTED | Request a challenge — use for high-risk transactions |
CHALLENGE_REQUESTED_AS_MANDATE | Mandate challenge — required for certain regulatory contexts |
Response
When 3DS authentication is required, the payment object includes a redirection object:
{
"id": "9a14962c-bdcf-49d1-8673-e75dfb48013f",
"amount": 4999,
"currency": "EUR",
"authorization": {
"status": "PENDING"
},
"authentication": {
"updated_at": "2020-08-25T10:42:59.123+02:00",
"status": "CREATED"
},
"redirection": {
"href": "https://pay.purse-sandbox.com/redirect/3ds?session=xyz",
"method": "GET",
"media_type": "application/json",
"body": "{\"data\": \"json data to be used for redirection\"}"
}
}
| Field | Description |
|---|---|
redirection.href | URL to redirect the customer to for 3DS authentication |
redirection.method | HTTP method to use for the redirection (GET or POST) |
redirection.media_type | Media type of the redirection payload (application/json or text/html) |
redirection.body | Body to send with the redirection, when applicable |
Redirect the customer using redirection.href and redirection.method to complete 3DS authentication. After authentication, the PSP redirects back to the shopper_redirection_url you provided.
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
- Token payment — pay with a saved card
- Complete payment flow — end-to-end guide