Payments
The payments endpoints of the Kashu API, with their parameters, objects, errors and examples. The guide explains how they fit together.
The payment object
| Field | Type | About |
|---|
id | string | An id that starts py_. |
object | string | Always "payment". |
amount | integer | In the currency's minor unit, such as cents for USD. More than 0. |
amount_capturable | integer | In the currency's minor unit, such as cents for USD. |
amount_captured | integer | In the currency's minor unit, such as cents for USD. |
amount_refunded | integer | In the currency's minor unit, such as cents for USD. |
currency | string | Three capital letters, such as USD. |
capture_method | enum | One of automatic, manual. |
status | enum | One of pending, requires_action, requires_capture, succeeded, failed, canceled, processing. |
store | string | An id that starts st_. |
customer | string or null | An id that starts cu_. |
payment_method | string or null | An id that starts pm_. |
subscription | string or null | The subscription this payment renewed, for a payment made on a schedule. An id that starts sb_. |
disputed | boolean | Whether the buyer has disputed the payment. The dispute never changes its amounts. |
description | string or null | |
statement_descriptor | string or null | |
failure_code | enum or null | One of card_declined, processing_error. |
decline_code | enum or null | One of generic_decline, insufficient_funds, do_not_honor, expired_card, incorrect_cvc, lost_card, stolen_card, fraudulent. |
next_action | object or null | |
next_action.type | string | Always "redirect_to_url". |
next_action.redirect_to_url | object | |
next_action.redirect_to_url.url | string | |
metadata | map of strings | |
livemode | boolean | |
created | integer | Unix seconds. |
{
"id": "py_1a2B3c4D5e6F7g8H9i0J1k2L",
"object": "payment",
"amount": 4999,
"amount_capturable": 0,
"amount_captured": 4999,
"amount_refunded": 0,
"currency": "USD",
"capture_method": "automatic",
"status": "succeeded",
"store": "st_1a2B3c4D5e6F7g8H9i0J1k2L",
"customer": "cu_1a2B3c4D5e6F7g8H9i0J1k2L",
"payment_method": "pm_1a2B3c4D5e6F7g8H9i0J1k2L",
"subscription": null,
"disputed": false,
"description": "Order 1001",
"statement_descriptor": "Example Shop",
"failure_code": null,
"decline_code": null,
"next_action": null,
"metadata": {
"order": "1001"
},
"livemode": false,
"created": 1762473600
}
POST /v1/payments
Charge a saved card or a card token, or authorize it with capture_method manual. A decline is a payment with status failed.
- Scope
payments:write
- Keys
- Secret, or restricted with the scope below.
- Idempotency-Key
- Required. This endpoint moves money. See Idempotency.
Parameters
| Name | In | Type | Required | About |
|---|
Idempotency-Key | header | string | Required | Required. Retry with the same key and get the same result. Up to 255 characters. |
Kashu-Version | header | string | Optional | The API version to answer in. Defaults to the key's pinned version. |
Request body
| Field | Type | Required | About |
|---|
amount | integer | Required | In the currency's minor unit, such as cents for USD. More than 0. Up to 99999999. |
currency | string | Required | Three capital letters, such as USD. |
payment_method | string | Optional | A saved card to charge. Give this or token. An id that starts pm_. |
token | string | Optional | A card token (tok_) to charge instead of a saved card; customer is then required. The card is saved for the customer and the token is spent. An id that starts tok_. |
customer | string | Optional | An id that starts cu_. |
capture_method | enum | Optional | One of automatic, manual. |
store | string | Optional | An id that starts st_. |
description | string | Optional | Up to 500 characters. |
statement_descriptor | string | Optional | Up to 22 characters. |
metadata | map of strings | Optional | Keys up to 40 characters, values up to 500. |
Errors
| Status | Codes |
|---|
| 400 | invalid_json, parameter_missing, parameter_invalid, parameter_unknown, api_version_invalid, idempotency_key_missing, idempotency_key_invalid, idempotency_key_reused, token_already_used, token_expired |
| 401 | api_key_missing, api_key_invalid, api_key_expired |
| 403 | livemode_unavailable, insufficient_scope, publishable_key_not_allowed, payments_not_enabled |
| 404 | resource_missing |
| 409 | idempotency_key_in_use, operation_in_progress |
| 429 | rate_limited |
| 500 | api_error |
Examples
curl https://api.kashupay.com/v1/payments \
-H "Authorization: Bearer $KASHU_SECRET_KEY" \
-H "Idempotency-Key: payments-create-1001" \
-H "Content-Type: application/json" \
-d '{"amount":4999,"currency":"USD","payment_method":"pm_1a2B3c4D5e6F7g8H9i0J1k2L","customer":"cu_1a2B3c4D5e6F7g8H9i0J1k2L"}'
const payment = await kashu("POST", "/v1/payments", {
"amount": 4999,
"currency": "USD",
"payment_method": "pm_1a2B3c4D5e6F7g8H9i0J1k2L",
"customer": "cu_1a2B3c4D5e6F7g8H9i0J1k2L"
}, { idempotencyKey: "payments-create-1001" });
console.log(payment.status);
GET /v1/payments
List payments, newest first.
- Scope
payments:read
- Keys
- Secret, or restricted with the scope below.
- Idempotency-Key
- Not used. A read changes nothing.
Parameters
| Name | In | Type | Required | About |
|---|
status | query | enum | Optional | One of pending, requires_action, requires_capture, succeeded, failed, canceled. |
limit | query | integer | Optional | At least 1. Up to 100. Defaults to 10. |
cursor | query | string | Optional | |
Kashu-Version | header | string | Optional | The API version to answer in. Defaults to the key's pinned version. |
Errors
Examples
curl "https://api.kashupay.com/v1/payments?limit=3" \
-H "Authorization: Bearer $KASHU_SECRET_KEY"
const list = await kashu("GET", "/v1/payments?limit=3");
console.log(list.has_more);
GET /v1/payments/{id}
Retrieve a payment.
- Scope
payments:read
- Keys
- Secret, or restricted with the scope below.
- Idempotency-Key
- Not used. A read changes nothing.
Parameters
| Name | In | Type | Required | About |
|---|
id | path | string | Required | An id that starts py_. |
Kashu-Version | header | string | Optional | The API version to answer in. Defaults to the key's pinned version. |
Errors
Examples
curl https://api.kashupay.com/v1/payments/py_1a2B3c4D5e6F7g8H9i0J1k2L \
-H "Authorization: Bearer $KASHU_SECRET_KEY"
const payment = await kashu("GET", "/v1/payments/py_1a2B3c4D5e6F7g8H9i0J1k2L");
console.log(payment.status);
POST /v1/payments/{id}/capture
Capture an authorized payment, once, for at most the amount held. Without an amount, all of it.
- Scope
payments:write
- Keys
- Secret, or restricted with the scope below.
- Idempotency-Key
- Required. This endpoint moves money. See Idempotency.
Parameters
| Name | In | Type | Required | About |
|---|
id | path | string | Required | An id that starts py_. |
Idempotency-Key | header | string | Required | Required. Retry with the same key and get the same result. Up to 255 characters. |
Kashu-Version | header | string | Optional | The API version to answer in. Defaults to the key's pinned version. |
Request body
| Field | Type | Required | About |
|---|
amount | integer | Optional | In the currency's minor unit, such as cents for USD. More than 0. Up to 99999999. |
Errors
| Status | Codes |
|---|
| 400 | invalid_json, parameter_missing, parameter_invalid, parameter_unknown, api_version_invalid, idempotency_key_missing, idempotency_key_invalid, idempotency_key_reused, payment_unexpected_state, amount_too_large |
| 401 | api_key_missing, api_key_invalid, api_key_expired |
| 403 | livemode_unavailable, insufficient_scope, publishable_key_not_allowed, payments_not_enabled |
| 404 | resource_missing |
| 409 | idempotency_key_in_use, operation_in_progress |
| 429 | rate_limited |
| 500 | api_error |
Examples
curl https://api.kashupay.com/v1/payments/py_1a2B3c4D5e6F7g8H9i0J1k2L/capture \
-H "Authorization: Bearer $KASHU_SECRET_KEY" \
-H "Idempotency-Key: payments-capture-1001" \
-H "Content-Type: application/json" \
-d '{"amount":4999}'
const payment = await kashu("POST", "/v1/payments/py_1a2B3c4D5e6F7g8H9i0J1k2L/capture", {
"amount": 4999
}, { idempotencyKey: "payments-capture-1001" });
console.log(payment.status);
POST /v1/payments/{id}/void
Release an authorized payment that has not been captured.
- Scope
payments:write
- Keys
- Secret, or restricted with the scope below.
- Idempotency-Key
- Required. This endpoint moves money. See Idempotency.
Parameters
| Name | In | Type | Required | About |
|---|
id | path | string | Required | An id that starts py_. |
Idempotency-Key | header | string | Required | Required. Retry with the same key and get the same result. Up to 255 characters. |
Kashu-Version | header | string | Optional | The API version to answer in. Defaults to the key's pinned version. |
Request body
Send no body, or an empty JSON object.
Errors
| Status | Codes |
|---|
| 400 | invalid_json, parameter_unknown, api_version_invalid, idempotency_key_missing, idempotency_key_invalid, idempotency_key_reused, payment_unexpected_state |
| 401 | api_key_missing, api_key_invalid, api_key_expired |
| 403 | livemode_unavailable, insufficient_scope, publishable_key_not_allowed, payments_not_enabled |
| 404 | resource_missing |
| 409 | idempotency_key_in_use, operation_in_progress |
| 429 | rate_limited |
| 500 | api_error |
Examples
curl https://api.kashupay.com/v1/payments/py_1a2B3c4D5e6F7g8H9i0J1k2L/void \
-X POST \
-H "Authorization: Bearer $KASHU_SECRET_KEY" \
-H "Idempotency-Key: payments-void-1001"
const payment = await kashu("POST", "/v1/payments/py_1a2B3c4D5e6F7g8H9i0J1k2L/void", undefined, { idempotencyKey: "payments-void-1001" });
console.log(payment.status);