Payments
This is where the core payment stuff happens -- starting a payment, handling 3D Secure, capturing money, reversing payments, and changing authorised amounts.
If you're using the Sessions flow, the Drop-in handles the payment and 3DS steps for you. You'll only need the post-authorisation bits (capture, reversal, amount update) if they apply to your setup.
All these endpoints mirror their Adyen equivalents. The request and response shapes are the same, so the Adyen docs work as a companion to these.
Start a payment
Kicks off a payment. The paymentMethod object comes straight from the Adyen Component's onSubmit callback -- just pass it through as-is.
This mirrors Adyen's /payments endpoint.
Request
POST /v1/ecom/{siteId}/payments
Path:
| Parameter | Type | What it is |
|---|---|---|
siteId | string | Your ecommerce site ID |
Headers:
| Header | Needed? | What to send |
|---|---|---|
Authorization | Yes | Bearer YOUR_API_KEY |
Content-Type | Yes | application/json |
Idempotency-Key | No | A unique key to stop duplicate payments. See Best Practices. |
Body:
| Field | Type | Needed? | What it is |
|---|---|---|---|
amount | object | Yes | How much to charge. |
amount.value | integer | Yes | Amount in minor units (so 1000 for 10.00). |
amount.currency | string | Yes | Three-letter currency code. |
paymentMethod | object | Yes | The payment method data from the Adyen Component's onSubmit callback. Just pass it through exactly as you got it. |
returnUrl | string (URI) | Yes | Where to send the customer after 3DS or a redirect. |
reference | string | No | Your own reference for this payment (up to 80 characters). |
Things we handle for you
- Shopper interaction: Automatically set to
Ecommerce. - Country code: Set to your merchant's registered country.
- Payment splits: Sorted out behind the scenes.
Response
You'll get back an Adyen PaymentResponse. Here are the key bits:
| Field | Type | What it is |
|---|---|---|
resultCode | string | What happened: Authorised, Refused, Pending, RedirectShopper, ChallengeShopper, etc. |
pspReference | string | Adyen's unique reference for this payment. You'll need this for captures, reversals, and amount changes. |
action | object | If the customer needs to do something extra (like 3DS), this tells you what. Pass it to the Adyen Component. |
What the result codes mean:
| Result | What happened | What to do next |
|---|---|---|
Authorised | The payment went through. | You're done. If you're using manual capture, capture it when you're ready. |
Refused | The payment was turned down. | Let the customer know and let them try again. |
Pending | It's still being processed. | Wait for a webhook with the final result. |
RedirectShopper | The customer needs to be redirected (like for 3DS or iDEAL). | Pass the action to the Adyen Component. |
ChallengeShopper | A 3DS challenge is needed. | Pass the action to the Adyen Component. |
Example
curl -X POST https://api.yeti.host/v1/ecom/YOUR_SITE_ID/payments \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": {
"value": 2500,
"currency": "GBP"
},
"paymentMethod": {
"type": "scheme",
"encryptedCardNumber": "adyenjs_...",
"encryptedExpiryMonth": "adyenjs_...",
"encryptedExpiryYear": "adyenjs_...",
"encryptedSecurityCode": "adyenjs_..."
},
"returnUrl": "https://your-shop.com/checkout/result",
"reference": "order-12345"
}'
The
paymentMethodobject above is just for illustration. In practice, you get it from the Adyen Component'sonSubmitcallback and pass it straight through.
Dealing with 3DS and redirects
If the response has an action object, the customer needs to do something extra (usually 3D Secure). Pass the action to the Adyen Component:
if (result.action) {
component.handleAction(result.action);
}
When the customer finishes, the Component fires its onAdditionalDetails callback. Take those details and send them to the payment details endpoint below.
What could go wrong
| Status | Code | What it means |
|---|---|---|
| 400 | yp_2002 | Something's wrong with the request |
| 403 | yp_1002 | Your API key isn't allowed to call this endpoint |
| 404 | yp_3004 | We can't find that site, or it's not an ecommerce site |
| 404 | yp_3005 | We can't find the merchant |
| 422 | yp_5003 | Your merchant account isn't set up for ECOM yet |
| 500 | yp_4006 | Something went wrong starting the payment |
Submit payment details
Sends the extra details needed to finish a payment -- usually after a 3D Secure challenge or redirect. You call this when the Adyen Component fires its onAdditionalDetails callback.
This mirrors Adyen's /payments/details endpoint.
Request
POST /v1/ecom/{siteId}/payments/details
Path:
| Parameter | Type | What it is |
|---|---|---|
siteId | string | Your ecommerce site ID (needed in the path, though the payment is identified by the details payload) |
Headers:
| Header | Needed? | What to send |
|---|---|---|
Authorization | Yes | Bearer YOUR_API_KEY |
Content-Type | Yes | application/json |
Idempotency-Key | No | A unique key to stop duplicates. |
Body:
| Field | Type | Needed? | What it is |
|---|---|---|---|
details | object | Yes | The details from the Adyen Component's onAdditionalDetails callback. Pass it through as-is. |
paymentData | string | No | Payment data string, if the Component gave you one. |
Response
Same shape as the start a payment response.
Example
curl -X POST https://api.yeti.host/v1/ecom/YOUR_SITE_ID/payments/details \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"details": {
"threeDSResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ=="
}
}'
What could go wrong
| Status | Code | What it means |
|---|---|---|
| 400 | yp_2002 | Something's wrong with the request |
| 403 | yp_1002 | Your API key isn't allowed to call this endpoint |
| 500 | yp_4004 | Something went wrong submitting the details |
Capture a payment
Takes the money from an authorised payment. You only need this if you're using manual capture -- if you're on auto-capture, payments are captured the moment they're authorised and you don't need to do anything.
This mirrors Adyen's /payments/{pspReference}/captures endpoint.
Auto vs manual capture
| Mode | What happens | Do you need this endpoint? |
|---|---|---|
| Auto-capture | The money is taken as soon as the payment is authorised. | No. |
| Manual capture | The payment is authorised but the money isn't taken yet. You decide when to capture. | Yes -- call this when you're ready (like when you ship the order). |
Request
POST /v1/ecom/{siteId}/payments/{pspReference}/captures
Path:
| Parameter | Type | What it is |
|---|---|---|
siteId | string | Your ecommerce site ID |
pspReference | string | The pspReference from the original payment |
Headers:
| Header | Needed? | What to send |
|---|---|---|
Authorization | Yes | Bearer YOUR_API_KEY |
Content-Type | Yes | application/json |
Idempotency-Key | No | A unique key to stop duplicate captures. |
Body:
| Field | Type | Needed? | What it is |
|---|---|---|---|
amount | object | Yes | How much to capture. |
amount.value | integer | Yes | Amount in minor units. Can be less than or equal to the original authorisation. |
amount.currency | string | Yes | Three-letter currency code. |
reference | string | No | Your reference for this capture (up to 80 characters). |
Response
An Adyen PaymentCaptureResponse:
| Field | Type | What it is |
|---|---|---|
pspReference | string | Adyen's reference for this capture. |
status | string | The capture status, like received. |
Example
curl -X POST https://api.yeti.host/v1/ecom/YOUR_SITE_ID/payments/ORIGINAL_PSP_REF/captures \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": {
"value": 2500,
"currency": "GBP"
},
"reference": "capture-order-12345"
}'
What could go wrong
| Status | Code | What it means |
|---|---|---|
| 400 | yp_2002 | Something's wrong with the request |
| 403 | yp_1002 | Your API key isn't allowed to call this endpoint |
| 404 | yp_3004 | We can't find that site, or it's not an ecommerce site |
| 404 | yp_3005 | We can't find the merchant |
| 500 | yp_4003 | Something went wrong capturing the payment |
Reverse a payment
Cancels or refunds a payment. You don't need to work out which one -- the API figures it out for you. If the payment hasn't been captured yet, it cancels it. If it has, it refunds it.
This mirrors Adyen's /payments/{pspReference}/reversals endpoint.
Request
POST /v1/ecom/{siteId}/payments/{pspReference}/reversals
Path:
| Parameter | Type | What it is |
|---|---|---|
siteId | string | Your ecommerce site ID |
pspReference | string | The pspReference from the original payment |
Headers:
| Header | Needed? | What to send |
|---|---|---|
Authorization | Yes | Bearer YOUR_API_KEY |
Content-Type | Yes | application/json |
Idempotency-Key | No | A unique key to stop duplicate reversals. |
Body:
| Field | Type | Needed? | What it is |
|---|---|---|---|
reference | string | No | Your reference for this reversal (up to 80 characters). |
Response
An Adyen PaymentReversalResponse:
| Field | Type | What it is |
|---|---|---|
pspReference | string | Adyen's reference for this reversal. |
status | string | The reversal status, like received. |
Example
curl -X POST https://api.yeti.host/v1/ecom/YOUR_SITE_ID/payments/ORIGINAL_PSP_REF/reversals \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference": "reversal-order-12345"
}'
What could go wrong
| Status | Code | What it means |
|---|---|---|
| 400 | yp_2002 | Something's wrong with the request |
| 403 | yp_1002 | Your API key isn't allowed to call this endpoint |
| 404 | yp_3004 | We can't find that site, or it's not an ecommerce site |
| 404 | yp_3005 | We can't find the merchant |
| 500 | yp_4005 | Something went wrong reversing the payment |
Update authorised amount
Changes how much is authorised on a payment before it's captured. This is useful when the final amount might be different from the original -- like hotel stays, car rentals, or when someone changes their order.
This mirrors Adyen's /payments/{pspReference}/amountUpdates endpoint.
Request
POST /v1/ecom/{siteId}/payments/{pspReference}/amount-updates
Path:
| Parameter | Type | What it is |
|---|---|---|
siteId | string | Your ecommerce site ID |
pspReference | string | The pspReference from the original payment |
Headers:
| Header | Needed? | What to send |
|---|---|---|
Authorization | Yes | Bearer YOUR_API_KEY |
Content-Type | Yes | application/json |
Idempotency-Key | No | A unique key to stop duplicate updates. |
Body:
| Field | Type | Needed? | What it is |
|---|---|---|---|
pspReference | string | Yes | The pspReference of the original payment. |
amount | object | Yes | The new amount. |
amount.value | integer | Yes | New amount in minor units. |
amount.currency | string | Yes | Three-letter currency code. |
reference | string | No | Your reference for this update (up to 80 characters). |
Response
An Adyen PaymentAmountUpdateResponse:
| Field | Type | What it is |
|---|---|---|
pspReference | string | Adyen's reference for this update. |
status | string | The update status, like received. |
Example
curl -X POST https://api.yeti.host/v1/ecom/YOUR_SITE_ID/payments/ORIGINAL_PSP_REF/amount-updates \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pspReference": "ORIGINAL_PSP_REF",
"amount": {
"value": 3500,
"currency": "GBP"
},
"reference": "amount-update-order-12345"
}'
What could go wrong
| Status | Code | What it means |
|---|---|---|
| 400 | yp_2002 | Something's wrong with the request |
| 403 | yp_1002 | Your API key isn't allowed to call this endpoint |
| 404 | yp_3004 | We can't find that site, or it's not an ecommerce site |
| 404 | yp_3005 | We can't find the merchant |
| 500 | yp_4007 | Something went wrong updating the amount |