{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"bc4d9034-c117-4938-b353-e20f5a190539","name":"Better API 2025-09-01","description":"## Overview\n\nThis guide provides detailed information about integrating with the Payment Authorization API. The API enables processing of payment transactions including authorization, capture, void, charge and refund operations.\n\n## Online (CIT) flow chart\n\n<img src=\"https://lh7-rt.googleusercontent.com/docsz/AD_4nXfB0MQQ4WwIIL7kFDzSzpSBSdyZgUzWEeNjt-g8piCWPvegFG4_0z0FoQXrQxXLC5dqtQDyx1H_2agENeJC9DBifV5ZuoqhSa01gYm03w32CbDTlqqPaGT10lOuI-JK_pDNIIJi4g?key=qelmDFYy1iA40AB_-hYa6chE\">\n\n## Subscription/recurring (MIT) flow chart\n\n<img src=\"https://lh7-rt.googleusercontent.com/docsz/AD_4nXf9tPOtBv5iQlgkQHdfkSeO3oT60FramzF9EE78DZ-tliCcAKWsujj0KuIf7VJRqwq8VQCOAg4qAUg0VLGdS08hh6Cz5-lMWjFceg4VGfVEjDKkZjP_Cp75rnpZH6SQnQPi-uULng?key=qelmDFYy1iA40AB_-hYa6chE\">\n\n## Authentication\n\nAll API requests require two headers:\n\n- `x-api-key`: Your API key for authentication\n    \n- `x-partner-id`: Your partner identifier\n    \n\n## Environment URLs\n\n- Sandbox: `https://sandbox-api.bettercharge.ai`\n    \n- Production: `https://api.bettercharge.ai`\n    \n\n### Error Handling\n\n- Always check HTTP status code\n    \n- Parse error response for details\n    \n- Implement appropriate retry logic\n    \n- Log all error responses\n    \n\n## Best Practices\n\n1. Always use TLS 1.2 or higher\n    \n2. Implement proper error handling\n    \n3. Store payment IDs for reference\n    \n4. Implement idempotency\n    \n5. Monitor API response times\n    \n6. Set appropriate timeouts\n    \n\n## Rate Limits\n\n- 100 requests per minute per API key\n    \n- 429 status code indicates rate limit exceeded\n    \n- Implement exponential backoff\n    \n\n## Payment States\n\nThe state field in the payment object represents the current status of a payment’s lifecycle. This state reflects the high-level status that clients should rely on.\n\n| State | Description |\n| --- | --- |\n| `RECEIVED` | The payment request was received and is pending approval process. |\n| `APPROVED` | The payment passed initial checks and is approved for further retry processing. |\n| `DECLINED` | The payment was declined during the approval process. |\n| `AUTHORIZED` | The payment was successfully authorized with the payment provider. |\n| `CAPTURED` | The funds have been successfully captured. |\n| `REFUNDED` | The payment has been refunded, either partially or in full. |\n| `VOIDED` | The payment was voided before capture. |\n| `FAILED` | The payment failed during processing due to an error or limit. |\n| `PROCESSING` | The payment is currently being processed. |\n| `STOPPED` | The payment retry process was stopped manually or automatically. |\n| `UNKNOWN` | A fallback state used when the current status is not recognized. This typically should not appear and may indicate an intermediate or transitional system state. |\n\n## Testing\n\n1. For testing purposes we support test card numbers/tokens, test email addresses (used for different response types)\n    \n2. Test all response scenarios. This can be achieved by the different test email addresses provided by Better\n    \n3. Verify error handling\n    \n4. Test timeout scenarios\n    \n\n### Available test cards for testing\n\nThe following card numbers can be used for testing in our Sandbox environment.\n\nUsing a test card in production will result with an error response, and the transaction will not be processed.\n\nUsing a card not from this list, in our Sandbox environment will result with an error response.\n\n| # | Card PAN |\n| --- | --- |\n| 1 | 4242424242424242 |\n| 2 | 4000056655665556 |\n| 3 | 5555555555554444 |\n| 4 | 2223003122003222 |\n| 5 | 5200828282828210 |\n| 6 | 5105105105105100 |\n| 7 | 378282246310005 |\n| 8 | 371449635398431 |\n| 9 | 6011111111111117 |\n| 10 | 6011000990139424 |\n| 11 | 6011981111111113 |\n| 12 | 3056930009020004 |\n| 13 | 36227206271667 |\n| 14 | 6555900000604105 |\n| 15 | 3566002020360505 |\n| 16 | 6200000000000005 |\n| 17 | 6200000000000047 |\n| 18 | 6205500000000000004 |\n| 19 | 4000000000000002 |\n| 20 | 4000000000009995 |\n| 21 | 4000000000009987 |\n| 22 | 4000000000009979 |\n| 23 | 4000000000000069 |\n| 24 | 4000000000000127 |\n| 25 | 4000000000000119 |\n| 26 | 4242424242424241 |\n| 27 | 4000000000006975 |\n\n### Emails for testing\n\nThe following email addresses can be used for testing in our Sandbox environment. Using these email addresses, you can illustrate different response codes.\n\n| Email | Response |\n| --- | --- |\n| [test.approve@bettercharge.ai](https://mailto:test.approve@bettercharge.ai) | {\"decision\": \"APPROVE\", \"confidence\": 75.7} |\n| [test.decline.insufficient_data@bettercharge.ai](https://mailto:test.decline.insufficient_data@bettercharge.ai) | {\"reason\": \"Insufficient data provided for model to make a decision\", \"decision\": \"DECLINE\", \"confidence\": 5} |\n| [test.decline.business_rules@bettercharge.ai](https://mailto:test.decline.business_rules@bettercharge.ai) | {\"reason\": \"Declined on business rules\", \"decision\": \"DECLINE\", \"confidence\": 0} |\n| [test.decline.model@bettercharge.ai](https://mailto:test.decline.model@bettercharge.ai) | {\"reason\": \"Declined by model decision\", \"decision\": \"DECLINE\", \"confidence\": 23} |\n| [test.approve.retry.successful@bettercharge.ai](https://mailto:test.approve.retry.successful@bettercharge.ai) | {\"decision\": \"APPROVE\", \"confidence\": 75.7} |\n| [test.approve.liability@bettercharge.ai](https://mailto:test.approve.liability@bettercharge.ai) | {\"decision\": \"APPROVE\", \"confidence\": 80} |\n\n### Tokens for testing\n\n| Token | Result |\n| --- | --- |\n| 2e6a7aaa539b7da318d6877ae81839c48907cea8a1196819f383e52e | Automatically approves |\n\n# BetterCharge API Error Responses\n\nThis document provides a comprehensive list of all error responses that can be returned by the BetterCharge API. All error responses follow a consistent structure with a `code`, `error`, and `message` field.\n\n## Error Response Structure\n\n``` json\n{\n  \"code\": \"ERROR_CODE\",\n  \"error\": \"Error Type\",\n  \"message\": \"Detailed error message\"\n}\n\n ```\n\n## Error Responses by HTTP Status Code\n\n### 400 Bad Request\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `BAD_REQUEST` | Bad Request | Missing or invalid fields: \\[field1, field2, ...\\] | Request validation failed due to missing or invalid required fields |\n| `CARD_EXPIRED` | Card already expired | Payment {bcId} declined: card expired | Payment declined because the card has expired |\n| `CARD_TOO_CLOSE_TO_EXPIRATION` | Card too close to expiration | Payment {bcId} declined: card too close to expiration | Payment declined because the card is too close to its expiration date |\n| `ERROR` | Error | Validation errors: \\[details\\] | Request validation failed (PSP Mock) |\n| `INVALID_ACCOUNT` | Invalid account | Invalid accountId provided | Invalid account ID provided in request |\n| `ERROR` | Error | Invalid refund request data | Invalid refund request data structure |\n| `ERROR` | Error | Invalid void request data | Invalid void request data structure |\n| `ERROR` | Error | Refund request declined due to policy restrictions | Refund declined due to policy restrictions |\n| `ERROR` | Error | Void request declined due to policy restrictions | Void declined due to policy restrictions |\n\n### 401 Unauthorized\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `UNAUTHORIZED` | unauthorized | Unauthorized | Invalid or missing authentication credentials |\n\n### 403 Forbidden\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `FORBIDDEN` | Forbidden | Forbidden | Merchant does not own the payment being accessed |\n\n### 404 Not Found\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `NOT_FOUND` | Not Found | Merchant {merchantId} does not exist | Merchant not found in the system |\n| `NOT_FOUND` | Not Found | Payment {bcId} does not exist | Payment not found in the system |\n| `PARTNER_NOT_FOUND` | Partner not found | Partner not found | Partner not found in the system |\n\n### 422 Unprocessable Entity\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `PAYMENT_NOT_FOUND` | Missing entity | Payment not found | Payment not found in the system |\n| `PAYMENT_ALREADY_APPROVED` | Already sent | Payment already sent for authorization | Payment has already been authorized |\n| `PAYMENT_ALREADY_REFUNDED` | Already refunded | Payment {bcId} already refunded | Payment has already been refunded |\n| `REFUND_EXCEEDED_REFUNDABLE_AMOUNT` | Exceeded refundable amount | Refund request for payment {bcId} has exceeded its refundable amount | Refund amount exceeds the available refundable amount |\n| `PAYMENT_ALREADY_CAPTURED` | Already captured | Payment {bcId} already captured | Payment has already been captured |\n| `PAYMENT_ALREADY_VOIDED` | Already voided | Payment {bcId} already voided | Payment has already been voided |\n| `PAYMENT_ALREADY_AUTO_VOIDED` | Already auto voided | Payment {bcId} already auto voided | Payment has already been automatically voided |\n| `PAYMENT_NOT_AUTHORIZED` | Not authorized | Payment {bcId} not authorized | Payment has not been authorized yet |\n| `PAYMENT_AMOUNT_MISMATCH` | Amount mismatch | Payment {bcId} has an amount mismatch | Payment amount does not match expected value |\n\n### 423 Locked\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `PAYMENT_LOCKED` | Currently unavailable | Currently unavailable for payment {identifier}, try again in a few seconds | Payment is temporarily locked and cannot be processed |\n\n### 500 Internal Server Error\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `INTERNAL_SERVER_ERROR` | Internal server error | Unknown internal server error, contact support | Generic internal server error |\n| `INTERNAL_SERVER_ERROR` | Internal Server Error | Internal Server Error | Generic internal server error (various services) |\n\n### 502 Bad Gateway\n\n| Error Code | Error Type | Message | Description |\n| --- | --- | --- | --- |\n| `EXTERNAL_SERVICE_ERROR` | Unable to process request | External service unavailable | External service (PSP) is unavailable |\n| `EXTERNAL_SERVICE_ERROR` | Unable to process request | External service responded with error: {error} | External service returned an error |\n\n## Payment Decline Reasons\n\nThe service may return specific system wide decline reasons:\n\n| Decline Reason | Description |\n| --- | --- |\n| `EXCHANGE_RATE_FOR_CURRENCY_NOT_FOUND` | Exchange rate for the specified currency was not found |\n| `SYSTEM_IS_INACTIVE` | The payment system is currently inactive |\n| `MERCHANT_IS_DISABLED` | The merchant account is disabled |\n| `MERCHANT_NOT_FOUND` | The merchant was not found in the system |\n| `FILTER_LIMIT_REACHED` | We are temporarily not approving new payments |\n| `COMMON_ERROR` | General payment processing error |\n| `MERCHANT_INITIATED` | Payment was declined because it is an MIT payment |\n\n## Rate Limiting\n\nAPI endpoints are subject to rate limiting. When rate limits are exceeded, the API will return a 429 status code with appropriate headers:\n\n``` http\nHTTP/1.1 429 Too Many Requests\nX-RateLimit-Limit: 100\nX-RateLimit-Remaining: 0\nX-RateLimit-Reset: 1640275200\n\n ```\n\n## Best Practices for Error Handling\n\n1. **Always check the HTTP status code** first to determine the general category of error\n    \n2. **Parse the error response body** to get specific error details\n    \n3. **Handle 4xx errors** by correcting the request and retrying\n    \n4. **Handle 5xx errors** by implementing exponential backoff and retry logic\n    \n5. **Log error details** for debugging and monitoring purposes\n    \n6. **Implement proper error handling** for network timeouts and connection issues\n    \n7. **Use the error codes** to provide meaningful feedback to end users\n    \n\n## Important note\n\nIn a case where Better calls the API for retries it is up to the partner to block another fallback to Better, which can happen in the following scenario:\n\nMerchant calls Partner → Partner calls PSP → PSP returns NSF → Partner calls Better → Better approves → Better retries using Partner API → Partner calls PSP → PSP returns NSF → Partner calls Better again ❌ → Better starts a new process\n\nIt is up to the partner to block the fallback to Better\n\n## Support\n\nContact [support@bettercharge.ai](https://mailto:support@bettercharge.ai) for assistanceAPI documentation for BetterCharge payment and merchant management services.API documentation for Better payment and connector services.","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"42148697","team":5949286,"collectionId":"bc4d9034-c117-4938-b353-e20f5a190539","publishedId":"2sB3HjLLsT","public":true,"publicUrl":"https://developer.bettercharge.ai","privateUrl":"https://go.postman.co/documentation/42148697-bc4d9034-c117-4938-b353-e20f5a190539","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"58b3b3"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":""},{"name":"title","value":""}],"appearance":{"default":"light","themes":[{"name":"dark","logo":"https://content.pstmn.io/cb253159-58b1-4fa5-8d0b-335bed9391dc/YmV0dGVyLWRhcmsucG5n","colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"58b3b3"}},{"name":"light","logo":"https://content.pstmn.io/c08f9d0a-8b7c-4d01-b937-9e80cb5d0e25/YmV0dGVyLWxpZ2h0LnBuZw==","colors":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"58b3b3"}}]}},"version":"8.11.4","publishDate":"2025-11-10T16:12:19.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"","description":""},"logos":{"logoLight":"https://content.pstmn.io/c08f9d0a-8b7c-4d01-b937-9e80cb5d0e25/YmV0dGVyLWxpZ2h0LnBuZw==","logoDark":"https://content.pstmn.io/cb253159-58b1-4fa5-8d0b-335bed9391dc/YmV0dGVyLWRhcmsucG5n"}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/2aac4e61c6244a484800adc00830bfc7ed3229b9320fde7c4f816f6d1e970e71","favicon":"https://res.cloudinary.com/postman/image/upload/v1732479091/team/4957be4d56f677cf72451fb646aacba6.ico"},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://developer.bettercharge.ai/view/metadata/2sB3HjLLsT"}