curl --request GET \
--url https://api.bachs.io/v1/payments/{payment_id} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.bachs.io/v1/payments/{payment_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.bachs.io/v1/payments/{payment_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.bachs.io/v1/payments/{payment_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"reference": "ord_12903",
"payment_id": "ch_1a2b3c4d5e6f",
"checkout_id": "chk_1M2N3o4P5q6R7s8T",
"status": "succeeded",
"is_refundable": true,
"amount": "75000.00",
"amount_paid": "75000.00",
"amount_remaining": "0.00",
"currency": "NGN",
"fee_usd": "0.70",
"fees": {
"amount": "1125.00",
"currency": "NGN"
},
"merchant_bears_cost": false,
"platform_fee": null,
"fee_paid_by": "merchant",
"payment_method": "NGN_BANK_TRANSFER",
"channel": "api",
"narration": "Order payment ORD-12903",
"meta": {
"order_id": "ORD-12903"
},
"message": "Successful",
"customer": {
"name": "Jane Doe",
"email": "jane@example.com"
},
"created_at": "2026-02-22T12:00:00.000Z",
"updated_at": "2026-02-22T12:01:30.000Z",
"completed_at": "2026-02-22T12:01:30.000Z"
}{
"detail": "Invalid request parameters",
"error_code": "VALIDATION_ERROR",
"errors": [
{
"field": "amount",
"message": "Amount must be a positive decimal string",
"type": "value_error"
}
]
}{
"detail": "Invalid API key",
"error_code": "UNAUTHORIZED"
}{
"detail": "API key does not have permission for this operation",
"error_code": "FORBIDDEN"
}{
"detail": "Resource not found",
"error_code": "NOT_FOUND"
}{
"detail": "Rate limit exceeded. Please retry after a few seconds.",
"error_code": "TOO_MANY_REQUESTS"
}{
"detail": "An unexpected error occurred. Please try again later.",
"error_code": "INTERNAL_SERVER_ERROR"
}Retrieve a payment
Retrieve a single payment by its charge ID, with the full object: amount, status, the customer, fees, the products paid for, refunds, and status history.
curl --request GET \
--url https://api.bachs.io/v1/payments/{payment_id} \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.bachs.io/v1/payments/{payment_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.bachs.io/v1/payments/{payment_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.bachs.io/v1/payments/{payment_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"reference": "ord_12903",
"payment_id": "ch_1a2b3c4d5e6f",
"checkout_id": "chk_1M2N3o4P5q6R7s8T",
"status": "succeeded",
"is_refundable": true,
"amount": "75000.00",
"amount_paid": "75000.00",
"amount_remaining": "0.00",
"currency": "NGN",
"fee_usd": "0.70",
"fees": {
"amount": "1125.00",
"currency": "NGN"
},
"merchant_bears_cost": false,
"platform_fee": null,
"fee_paid_by": "merchant",
"payment_method": "NGN_BANK_TRANSFER",
"channel": "api",
"narration": "Order payment ORD-12903",
"meta": {
"order_id": "ORD-12903"
},
"message": "Successful",
"customer": {
"name": "Jane Doe",
"email": "jane@example.com"
},
"created_at": "2026-02-22T12:00:00.000Z",
"updated_at": "2026-02-22T12:01:30.000Z",
"completed_at": "2026-02-22T12:01:30.000Z"
}{
"detail": "Invalid request parameters",
"error_code": "VALIDATION_ERROR",
"errors": [
{
"field": "amount",
"message": "Amount must be a positive decimal string",
"type": "value_error"
}
]
}{
"detail": "Invalid API key",
"error_code": "UNAUTHORIZED"
}{
"detail": "API key does not have permission for this operation",
"error_code": "FORBIDDEN"
}{
"detail": "Resource not found",
"error_code": "NOT_FOUND"
}{
"detail": "Rate limit exceeded. Please retry after a few seconds.",
"error_code": "TOO_MANY_REQUESTS"
}{
"detail": "An unexpected error occurred. Please try again later.",
"error_code": "INTERNAL_SERVER_ERROR"
}Authorizations
Bearer token authentication. Pass your API key as Authorization: Bearer sk_.... See Authentication for keys, scopes, and sandbox vs production.
Path Parameters
Charge ID of the payment.
Response
Success - Payment retrieved
Detailed payment response for API integrations.
Unique identifier for the payment.
"pay_1a2b3c4d5e"
Current status of the payment. created: the charge exists and no attempt has succeeded yet. processing: an attempt is in flight and is being verified. succeeded: the payment is confirmed and settled in full. accepted: an underpayment or overpayment was accepted as final settlement. failed: the payment failed and no funds were captured. expired: the payment window elapsed before any payment arrived. cancelled: cancelled before completion. refunded: the full amount was returned to the customer. partially_refunded: part of the amount was returned to the customer. auto_refunded: we automatically returned the full amount to the customer. underpaid: the customer paid less than the amount owed. overpaid: the customer paid more than the amount owed.
created, processing, succeeded, accepted, failed, expired, cancelled, refunded, partially_refunded, auto_refunded, underpaid, overpaid "succeeded"
Requested amount in currency.
"10.00"
Payment currency code.
"USD"
Creation timestamp.
"2026-04-27T12:00:00Z"
Last update timestamp.
"2026-04-27T12:00:05Z"
Checkout reference when available.
"order_9876"
Why this payment exists. purchase: a one-time purchase. subscription_create: the first cycle of a new subscription. subscription_cycle: a subscription renewal. subscription_update: an off-cycle charge from a mid-cycle plan change (proration).
purchase, subscription_create, subscription_cycle, subscription_update "purchase"
Checkout identifier, when linked.
"chk_8T9u0V1w2X3y4Z5a"
Whether this payment can currently be refunded.
true
Amount received so far.
"10.00"
Remaining amount still expected.
"0.00"
Processing fee for this payment, converted to USD and expressed as a decimal string. null until the payment settles.
"0.59"
The processing fee on this payment, in the currency it was charged in. Prefer this over fee_usd when the payment was not collected in USD: fee_usd is a conversion of the same fee, this is the amount actually taken. null on a payment that carries no processing fee. See Fees.
Show child attributes
Show child attributes
Whether merchant bears processing cost.
true
What the platform took out of this sale, beside the gross it was taken from, in the base currency of the sale. null when the charge carried no platform fee, and on a charge that split the sale with transfer_data.amount instead. See Platform fees.
null
The seller's contracted share of this sale, in the base currency of the sale. Null on a charge that carries no split, and on one that split the sale with platform_fee instead.
null
Who Bachs's processing fee actually came from on this charge, read back from the ledger posting rather than a flag decided in advance. merchant: the fee came out of the charge. platform: the platform's own balance covered it. On a destination charge this never reads platform; the fee always comes from the charge there. See Processing fees.
merchant, platform "merchant"
How the payment was collected, usually named by rail and currency together, such as USD_CARD, NGN_CARD, NGN_BANK_TRANSFER, MOMO_GHS, or CRYPTO. A payment requested with a general method name can return BANK_TRANSFER or MOBILE_MONEY, so accept both forms for the same rail; null means the payment never reached a provider.
"NGN_BANK_TRANSFER"
Origin channel (for example api).
"checkout"
payment description/narration.
"Pro plan"
Public metadata stored for this payment.
{ "order_id": "ORD-9876" }
Human-readable payment message derived from status.
"Successful"
Customer information when available.
Show child attributes
Show child attributes
The line items this payment covers.
Show child attributes
Show child attributes
The subscription this payment belongs to, or null for a one-time purchase.
null
The invoice this payment collected. Present only for subscription payments; null for one-time purchases.
Show child attributes
Show child attributes
IDs of any refunds issued for this payment. null if no refund has been created.
["ref_1a2b3c4d5e"]
Chronological list of status changes for this payment.
Show child attributes
Show child attributes
Who paid and how, read from the attempt that succeeded. Returned on a single payment and on the collection.succeeded webhook, not on the payment list. null on payments taken before this field existed, and on payment methods that tell us nothing about the payer.
The shape is keyed by type. For bank_transfer, the bank_transfer object carries sender_name, sender_bank, sender_bank_code, sender_account_number (the full account the money came from, which you need to send money back to the sender), session_id (the interbank reference for the transfer) and narration. Which of those are present depends on what the sending bank passed on, so treat each as optional. It also carries a virtual_account object naming the account number the money landed in: id, account_number, bank_name, type (permanent for an account you keep, one_time for a number created for a single checkout) and expires_at.
{
"type": "bank_transfer",
"bank_transfer": {
"sender_name": "JANE ADEYEMI",
"sender_bank": "Guaranty Trust Bank",
"sender_account_number": "2294879124",
"session_id": "000013260922104115000821734502",
"virtual_account": {
"id": "va_8Hs2kQ4mZpXv",
"account_number": "9902847361",
"bank_name": "Example Bank",
"type": "permanent",
"expires_at": null
}
}
}
Completion timestamp when available.
"2026-04-27T12:00:05Z"

