# Create a session
Source: https://docs.tabby.ai/api-reference/checkout/create-a-session
post /api/v2/checkout
Creates a Checkout session. Creates Session and Payment, returns Pre-Scoring result (status), ids of Payment and Session.
# Session creation payload model
Source: https://docs.tabby.ai/api-reference/checkout/session-payload-model
The payload example for a session creation request with all required fields for a direct API custom integration can be found here:
```JSON theme={"dark"}
{
"payment": {
"amount": "100", // required. Up to 2 decimals for UAE and KSA, e.g. 100.00
"currency": "AED", // required. Use the ISO 4217 standard for defining currencies
"description": "test payload",
"buyer": {
"name": "John Doe", // required. Customer's full name
"email": "jsmith@example.com", //required. Customer's email address
"phone": "500000001", //required. Customer's phone number
"dob": "2000-01-20"
},
"shipping_address": {
"city": "Dubai", // required. Name of city, municipality, or village
"address": "Dubai", // required. Building name, apartment number
"zip": "1111" // required. Postal code
},
"order": {
"reference_id": "1001", // required. Merchant-assigned order number.
"updated_at": "2023-11-07T05:31:56Z",
"tax_amount": "0.00",
"shipping_amount": "0.00",
"discount_amount": "0.00",
"items": [
{
"reference_id": "SKU123",
"title": "Name of the product", // required. Name of the product.
"description": "Description of the product",
"quantity": 1, // required. Quantity of the product ordered. Should be >= 1
"unit_price": "0.00", // required. Price per unit of the product. Should be positive or zero.
"discount_amount": "0.00",
"image_url": "https://example.com/",
"product_url": "https://example.com/",
"gender": "Kids",
"category": "Clothes", // required. Name of high-level category (Clothes, Electronics,etc.)
"color": "white",
"product_material": "cotton",
"size_type": "EU",
"size": "M",
"brand": "Name of the Brand",
"is_refundable": true,
"barcode": "12345678",
"ppn": "MNXT2ZM/A",
"seller": "Name of the Seller"
}
]
},
"buyer_history": {
"registered_since": "2023-11-07T05:31:56Z", // required. Date and time the customer got registred with you
"loyalty_level": 0, // required. Customer's loyalty level within your store
"wishlist_count": 0,
"is_social_networks_connected": true,
"is_phone_number_verified": true,
"is_email_verified": true
},
"order_history": [
{
"purchased_at": "2023-11-07T05:31:56Z", // required. Date and time the order was placed
"amount": "100", // required. Up to 2 decimals for UAE and KSA, e.g. 100.00
"payment_method": "card",
"status": "new", // required. Status of the order
"buyer": {
"name": "John Doe", // required. Customer's full name
"email": "jsmith@example.com", //required. Customer's email address
"phone": "500000001", //required. Customer's phone number
"dob": "2000-01-20"
},
"shipping_address": {
"city": "Dubai", // required. Name of city, municipality, or village
"address": "Dubai", // required. Building name, apartment number
"zip": "1111" // required. Postal code
},
"items": [
{
"reference_id": "SKU123",
"title": "Name of the product",
"description": "Description of the product",
"quantity": 1,
"unit_price": "0.00",
"discount_amount": "0.00",
"image_url": "https://example.com/",
"product_url": "https://example.com/",
"gender": "Kids",
"category": "Clothes",
"color": "white",
"product_material": "cotton",
"size_type": "EU",
"size": "M",
"brand": "Name of the Brand",
"is_refundable": true,
"barcode": "12345678",
"ppn": "MNXT2ZM/A",
"seller": "Name of the Seller"
}
]
}
],
"meta": {
"customer": "#customer-id",
"order_id": "#1234"
},
"attachment": {
"body": "{\"flight_reservation_details\": {\"pnr\": \"TR9088999\",\"itinerary\": [...],\"insurance\": [...],\"passengers\": [...],\"affiliate_name\": \"some affiliate\"}}",
"content_type": "application/vnd.tabby.v1+json"
}
},
"lang": "en", // required. Session language
"merchant_code": "code provided to you from Tabby side", // required. Merchant's branch code
"merchant_urls": {
"success": "https://your-store/success",
"cancel": "https://your-store/cancel",
"failure": "https://your-store/failure"
},
"token": null
}'
```
# Approve disputes
Source: https://docs.tabby.ai/api-reference/disputes/approve-disputes
post /api/v1/disputes/approve
Approve disputes (refund money to the customer). Only 20 disputes can be approved within a single request.
# Challenge disputes
Source: https://docs.tabby.ai/api-reference/disputes/challenge-disputes
post /api/v1/disputes/challenge
Challenge disputes (request Tabby support to take a look at the case). Only 20 disputes can be challenged within a single request. Only disputes with status 'new' might be challenged.
# Get dispute by id
Source: https://docs.tabby.ai/api-reference/disputes/get-dispute-by-id
get /api/v1/disputes/{disputeId}
Returns detailed information about dispute.
# Get disputes list
Source: https://docs.tabby.ai/api-reference/disputes/get-disputes-list
get /api/v1/disputes
Returns list of 100 recently created disputes.
# Provide evidence for a dispute
Source: https://docs.tabby.ai/api-reference/disputes/provide-evidence
post /api/v1/disputes/{disputeId}/provide-evidence
Provide evidence (text and/or attachments) for a dispute. Used by the merchant to submit proof in response to an evidence request.
# Upload attachment
Source: https://docs.tabby.ai/api-reference/disputes/upload-attachment
post /api/v1/disputes/attachments/upload
Upload an attachment. Attachment must be in PNG, JPEG or PDF format and can be up to 5 megabytes in size. Files larger than 5 MB are rejected.
# API Reference Documentation
Source: https://docs.tabby.ai/api-reference/overview
In this part of the documentation all the needed API calls for Tabby Integration can be found and tested:
* Checkout - it is a whole process of customer data collection and payment authorization.
* Payments - the core of Tabby is a payments flow enabling you to handle payments at your webstore.
* Webhooks - serve to ensure a seamless payment verification flow.
* Disputes - help merchants resolve issues with customers orders more efficiently.
## Base URLs
Tabby uses region-specific domains. Choose the base URL based on the merchant's operating country:
| Region | API Base URL | Checkout / Promo | Merchant Dashboard |
| --------------- | ---------------------- | ------------------- | ------------------- |
| **UAE, Kuwait** | `https://api.tabby.ai` | `checkout.tabby.ai` | `merchant.tabby.ai` |
| **KSA** | `https://api.tabby.sa` | `checkout.tabby.sa` | `merchant.tabby.sa` |
All API paths and payloads are identical across both domains. Tabby identifies the environment (test or live) based on the API keys used.
| Contact | UAE, Kuwait | KSA |
| -------------------- | ------------------ | ------------------ |
| **Partner Support** | `partner@tabby.ai` | `partner@tabby.sa` |
| **Customer Support** | `help@tabby.ai` | `help@tabby.sa` |
## OpenAPI Specification
To access and download the raw OpenAPI specification file kindly use this: [openapi.yaml](https://docs.tabby.ai/openapi.yaml).
You can also view this API specification using [ReDoc](https://redocly.github.io/redoc/?url=https://docs.tabby.ai/openapi.yaml), the same is present below:
## Quick Links to Documentation
* [Direct API Integration Guide](/pay-in-4-custom-integration/quick-start)
* [Testing Credentials](/testing-guidelines/testing-credentials)
* [Postman API Collection](/testing-guidelines/postman-api-collections)
# Capture a payment
Source: https://docs.tabby.ai/api-reference/payments/capture-a-payment
post /api/v2/payments/{id}/captures
Send a Capture requests for Authorized payments only. If you capture the full payment amount, the payment will be automatically closed with full capture. If you capture partial amount, the payment will remain Authorized until the rest of the amount is captured or Close request sent.
# Close a payment
Source: https://docs.tabby.ai/api-reference/payments/close-a-payment
post /api/v2/payments/{id}/close
Closed is the final status of the payment. Your payment is going to be closed automatically if you capture the full amount of the payment. If an order is fully cancelled, please close the payment without capturing it - the customer will be refunded for all paid amount. If only a part of the order is delivered, please capture this part and close the payment – it will mean that another part of the order is not going to be delivered to the customer.
# List of all payments
Source: https://docs.tabby.ai/api-reference/payments/list-of-all-payments
get /api/v2/payments
Returns a list of success payments (`AUTHORIZED` or `CLOSED`) you’ve previously created. The payments are returned in sorted order, with the most recent payments appearing first. Each entry in the array is a separate payments object, including the status, any captures and any refunds. If no more payments are available, the resulting array will be empty. Payments might be filtered by creation date.
# Refund a payment
Source: https://docs.tabby.ai/api-reference/payments/refund-a-payment
post /api/v2/payments/{id}/refunds
Send a full or partial refund amount request. You can only refund the payment that has Closed status. By default refunds reflect instantly, which means Tabby initiates a refund through payment gateway.
# Retrieve a payment
Source: https://docs.tabby.ai/api-reference/payments/retrieve-a-payment
get /api/v2/payments/{id}
Retrieves the specified payment. Returns the entire payment object, including the payment Status, Captures and Refunds objects.
# Update a payment
Source: https://docs.tabby.ai/api-reference/payments/update-a-payment
put /api/v2/payments/{id}
Updates the reference_id. You can only use this endpoint to update this 1 field. If you send other fields in the request, they will simply be ignored by tabby. The payment to be updated can have a status of AUTHORIZED or CLOSED.
# Register a webhook
Source: https://docs.tabby.ai/api-reference/webhooks/register-a-webhook
post /api/v1/webhooks
Creates a new webhook. Webhooks are registered per `merchant_code` and per environment:
the environment is determined by the secret key you authorize the request with —
a production key (`sk_...`) registers webhooks for production payments, a test key
(`sk_test_...`) registers webhooks for test payments. Each `merchant_code` + key pair
can have up to 4 webhooks.
# Remove a webhook
Source: https://docs.tabby.ai/api-reference/webhooks/remove-a-webhook
delete /api/v1/webhooks/{id}
Removes the specified webhook.
# Retrieve a webhook
Source: https://docs.tabby.ai/api-reference/webhooks/retrieve-a-webhook
get /api/v1/webhooks/{id}
Retrieves the specified webhook.
# Retrieve all webhooks
Source: https://docs.tabby.ai/api-reference/webhooks/retrieve-all-webhooks
get /api/v1/webhooks
Retrieves all registred webhooks.
# Update a webhook
Source: https://docs.tabby.ai/api-reference/webhooks/update-a-webhook
put /api/v1/webhooks/{id}
Updates the specified webhook.
# ExpandCart
Source: https://docs.tabby.ai/e-commerce-platforms/expandcart
You can find Tabby settings in Home -> Payment -> Payment providers.
Please, make sure you have the following settings for the proper functioning:
)}
/>
Tabby Settings page
Promotions theme
No price snippet
Promo only mode
Promotions theme
No price snippet
Webhook Verification Key
Tabby promotions theme
No price snippet
Promo only mode
Multi currency → Checkout → Checkout currency
This page gives you answers to the most common questions about Tabby operating.
401 Not authorized. Error codes for a session creation request can be found here: Session Creation Error Codes.
In this case kindly contact Tabby Partner Support at `partner@tabby.ai` (or `partner@tabby.sa` for KSA) or reach out to your assigned Business Manager. When doing so, kindly include:
1. your store name as registered with Tabby;
2. your integration details:
* website URL or app name (for online integrations);
* description of offline integration, if applicable.
### Test Credentials
To test your custom integration with Tabby you need to use the following:
* your testing keys, starting with pk\_test / sk\_test;
* download the Postman API Collection from here: Postman API Collection;
* or use Tabby endpoints provided here: API Playground;
api.tabby.ai for UAE and Kuwait, or api.tabby.sa for KSA (see Base URLs). Payments can be created:
* in test mode using **Test API keys** from merchants' DEV and Stage environments;
* in live mode using **Live API keys**. Live keys are shared after development is completed and QA by Tabby team is done and confirmed.
CANCELLED on Tabby Merchant Dashboard: [https://docs.tabby.ai/api-reference/payments/close-a-payment](https://docs.tabby.ai/api-reference/payments/close-a-payment)
* Capture API call captures the payment, the payment gets status CAPTURED on Tabby Merchant Dashboard: [https://docs.tabby.ai/api-reference/payments/capture-a-payment](https://docs.tabby.ai/api-reference/payments/capture-a-payment)
## How can I verify Payments via Webhooks?
Main article: Webhooks.
There are 3 ways to secure the Webhook notifications:
* allow these IP-addresses for Webhooks:
```
34.166.36.90
34.166.35.211
34.166.34.222
34.166.37.207
34.93.76.191
34.166.128.182
34.166.170.3
34.166.249.7
```
* add static AUTH HEADER during webhook registration: [https://docs.tabby.ai/api-reference/webhooks/register-a-webhook](https://docs.tabby.ai/api-reference/webhooks/register-a-webhook)
* webhooks should be treated as notifications only. To verify the payment status, use the payment\_id from the webhook and call the getPayment API: [https://docs.tabby.ai/api-reference/payments/retrieve-a-payment](https://docs.tabby.ai/api-reference/payments/retrieve-a-payment)
## What should I do if Payments remain in status NEW in Tabby Merchant Dashboard?
Associated articles:
* Payment Statuses;
* Payment Processing.
### Self-Hosted Platforms
Self-Hosted Platforms are: **WooCommerce, Shopify, Magento 2, OpenCart**.
These payments are likely lost (not linked to any created order). Merchants should select one of the options:
* either cancel them (i.e., refund the customer): [https://docs.tabby.ai/api-reference/payments/close-a-payment](https://docs.tabby.ai/api-reference/payments/close-a-payment)
* or manually create an order for such payments, as they are authorized by Tabby, and capture payments: [https://docs.tabby.ai/api-reference/payments/capture-a-payment](https://docs.tabby.ai/api-reference/payments/capture-a-payment)
* or just capture them if the orders exist.
Additionally, merchants should update the plugin to the latest version (following Tabby documentation) and check the plugin settings to prevent similar cases in the future.
### Zid and Salla Platforms
By default, everything is expected to be working successfully when live keys are saved. If you suspect an issue or have lost orders, kindly re-save the keys and contact your platform's support team to verify the situation or register webhooks to prevent such issues.
### Custom (Direct API) Integrations
Merchants may have immediate or delayed captures, meaning NEW statuses may simply be waiting for merchant action. However, in many cases, these payments are also lost.
Merchants should select one of the options:
* either cancel them (i.e., refund the customer): [https://docs.tabby.ai/api-reference/payments/close-a-payment](https://docs.tabby.ai/api-reference/payments/close-a-payment)
* or manually create an order for such payments, as they are authorized by Tabby, and capture payments: [https://docs.tabby.ai/api-reference/payments/capture-a-payment](https://docs.tabby.ai/api-reference/payments/capture-a-payment)
* or just capture them if the orders exist.
Merchants should also check payment logs and investigate integration issues to determine why the payment wasn't acknowledged or captured in time (following Tabby documentation).
The Integrations team can assist with investigating API calls and webhooks - kindly contact them via the integrations thread or an assigned business manager.
### Tabby Card and Payment Links
These are always expected to be Auto-Captured. If they are not - kindly provide your store name with Tabby to Tabby Partner Support `partner@tabby.ai` / `partner@tabby.sa` or to your assigned business manager.
## What is Eligibility check?
Associated articles:
* Background Pre-scoring Check;
* Integration overview.
### How can I know that a customer is not eligible to use Tabby?
In the Tabby Session creation response, you can receive a status like this if a customer is not eligible to use Tabby:
```
"status": "rejected",
"configuration"."products"."installments"."rejection_reason": "not_available"
```
You need to hide Tabby payment option or show it with the General Rejection message or specific reason message depending on the "rejection\_reason" value:
| Reason | English | Arabic |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| General Rejection (`not_available`) | Sorry, Tabby is unable to approve this purchase. Please use an alternative payment method for your order. | نأسف، تابي غير قادرة على الموافقة على هذه العملية. الرجاء استخدام طريقة دفع أخرى. |
| `order_amount_too_high` | This purchase is above your current spending limit with Tabby, try a smaller cart or use another payment method | قيمة الطلب تفوق الحد الأقصى المسموح به حاليًا مع تابي. يُرجى تخفيض قيمة السلة أو استخدام وسيلة دفع أخرى. |
| `order_amount_too_low` | The purchase amount is below the minimum amount required to use Tabby, try adding more items or use another payment method | قيمة الطلب أقل من الحد الأدنى المطلوب لاستخدام خدمة تابي. يُرجى زيادة قيمة الطلب أو استخدام وسيلة دفع أخرى. |
For detailed implementation guide check here: Background Pre-scoring Check
### What is the difference between eligibility check and checkout session creation?
Tabby's Checkout API serves two distinct purposes. Here's a side by side comparison:
| Aspect | Eligibility Check | Checkout Session Creation |
| ------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------ |
| **Purpose** | Determine if customer can use Tabby | Create payment session for actual checkout |
| **Timing** | Before showing Tabby payment method | When customer clicks "Place order" |
| **Payload** | Minimal (amount, currency, buyer) | Complete (all order details, items, shipping, merchant URLs) |
| **Response** | Status (`created` or `rejected`) + rejection reason | Status + `web_url` for redirect + `payment.id` |
| **Next Step** | Show or hide / mark unavailable Tabby payment method based on the response | Redirect to Tabby Hosted Payment Page |
### Example of a minimal payload for eligibility check
```json theme={"dark"}
{
"payment": {
"amount": "340.00",
"currency": "SAR",
"buyer": {
"email": "otp.success@tabby.ai",
"phone": "+966500000001"
}
},
"merchant_code": "your_merchant_code"
}
```
**Key principle**: Use the same endpoint (`POST /api/v2/checkout`) but with different payload sizes for different purposes.
### When should I perform eligibility check?
Perform the eligibility check **once per checkout session** before displaying payment methods to customer, when you have the basic order details (amount, currency, buyer.phone, buyer.email).
**Best practices:**
* **Payload**: Include as much data as possible (not just minimal payload) for better approval rates and conversion
* **Timing**: Check eligibility when customer enters checkout page with all main data available
* **Error handling**: If API times out or returns error, default to showing Tabby option (fail-safe approach) - never block checkout
* **Two separate calls**: Eligibility check (minimal/recommended data) ≠ Session creation (complete order details when customer clicks "Place order")
## How should I validate checkout session response?
Always validate the checkout session response before redirecting the customer. Here are the critical validation steps:
**Critical Validation Steps**:
1. **Check `status` field** - must be `"created"`. If `"rejected"`, show rejection message and don't redirect;
2. **Validate `web_url` presence** - never redirect without it. Show rejection message if missing;
3. **Store `payment.id`** - required for subsequent capture/refund operations.
For complete validation logic and edge cases check here: Checkout Flow - Response Validation.
## Is it possible to know the rejection reason for payments?
Unfortunately, due to compliance and regulatory restrictions, Tabby is not permitted to disclose the specific rejection reasons to merchants. Customers, however, typically see a rejection message on the Tabby-hosted payment page at the time of the transaction.
If you suspect a technical issue that may be causing multiple or all transactions to be rejected - please, contact Tabby Partner Support at `partner@tabby.ai` (or `partner@tabby.sa` for KSA) or reach out to your assigned Business Manager. When doing so, kindly include:
1. your store name as registered with Tabby;
2. your integration details:
* website URL or app name (for online integrations);
* description of offline integration, if applicable.
## Are there any transaction limits set for my store from Tabby side?
Tabby applies transaction limits based on a combination of factors, including your industry and associated risk levels. Additionally, customer-level limits are dynamically determined based on their historical transaction behaviour with your store and with other merchants using Tabby.
For this reason, we recommend **not setting hardcoded limits** for Tabby transactions on your end, as these may conflict with Tabby's dynamic risk and approval models.
## What should I do if a customer is not redirected back to the website?
When customers finish the Tabby session, they are redirected back to your site from the Tabby Payment Page via one of the three merchant\_urls, with the payment\_id after the separator, e.g. [https://your-store/success?payment\_id=string](https://your-store/success?payment_id=string):
```
"merchant_urls": {
"success": "https://your-store/success",
"cancel": "https://your-store/cancel",
"failure": "https://your-store/failure"
}
```
The merchant\_urls should be included in a Session Creation request sent to Tabby from your side.
## What should I do if I do not receive fields in a response from Tabby API?
If some fields do not return in the response:
* check the endpoint used for the request;
* check the fields format in the request - they should match those specified in the API Reference Documentation;
* check responses in the API Reference Documentation and that these fields are expected to be returned.
## Where can I see if Tabby is working normally?
Status Page Recommendations. Associated article: Technical Requirements -> Status Page.
Recommendations for status page maintenance and incidents:
* Tabby sends alerts through [https://www.tabby-status.com/](https://www.tabby-status.com/). Please, subscribe using your preferred channel for updates.
* Tabby posts alerts manually in real-time within 5-10 minutes of identifying and confirming an issue. The alerts provide details about the affected systems.
* If Checkout or Payments APIs are affected for all countries, we recommend disabling Tabby until the next message confirms the resolution.
* If only one country is affected, you can disable Tabby for that specific country.
* If non-real-time systems are affected, no action is required (incident details will still be posted).
* If you see a Scheduled Technical Maintenance notification, you can plan disabling Tabby for that duration of the maintenance window or mute monitors if the expected timeframe is less than 10 minutes, as it will recover automatically.
* If you suspect an issue with any flow, you can contact Tabby Partner Support `partner@tabby.ai` / `partner@tabby.sa` for more details. However, if you observe that Tabby APIs are not working (e.g., consistently returning 5xx or 4xx errors), please contact the Tabby Integrations Team via the integration thread or via your assigned business manager immediately to investigate and resolve the issue. In the meantime, disable Tabby until the issue is resolved.
## General information
For additional support and information, you may also find helpful resources here: Tabby Support Center.
# Quick Start
Source: https://docs.tabby.ai/introduction/quick-start
Choose your integration type below. Use pre-built plugins for popular platforms or implement custom integration via Tabby API.
## Custom Integrations
This page gives you the common knowledge about Tabby operating.
merchant\_code represents a merchant country or a specific store within the country.
### Dates
The
ISO 8601 standard with combined Date and Time in UTC for all API dates. The exceptions to this are dob fields where we accept values in the **YYYY-MM-DD** format.
```JSON theme={"dark"}
{
"registered_since": "2019-08-24T14:15:22Z",
"dob": "2019-08-24"
}
```
### Locale
Operating in the GCC region, Tabby supports the English and Arabic languages and refers to the
RFC 1766 standard.
```JSON theme={"dark"}
{
"lang": "en"
}
```
### String Length Validation
We are processing a maximum of 255 symbols in the **"string"** field.
### Allowed characters in redirect URLs ("success", "cancel", "failure")
1. Latin letters (a-z, A-Z)
2. Arabic letters (ء-ي)
3. Digits (0-9)
4. Special characters - \ | / : ;., + \{}? & @ = # %
## Rate limit
API rate limiting is implemented to maintain stable operations for Tabby services. If an excessive number of requests are sent in a short time, rate limiting may be applied to your requests.
The response will include an HTTP status code 429 error when rate limiting is triggered.
Rate limits are enforced per API Key and are measured on a per-operation basis. Operations are categorized into **Create Session** and **Payment** operations.
* **Live API Keys**: The rate limit is 200 Create Session operations per 10 seconds, while other operations are limited to 100 requests per second.
* **Testing API Keys**: The rate limit is 10 requests per 10 seconds for Create Session operations and 50 requests per second for other operations.
401 Not authorized. More information on HTTP Basic auth can be found in the API Reference article.
## Errors
Tabby APIs use HTTP status codes alongside the error objects to handle errors. When an API call fails, Tabby will respond with a 4xx status code and a response body containing an error object with the error code, an array of error messages and a unique correlation ID to identify the request.
The error object contains an error\_code and an errorType value (or errors).
The error object is a human-readable English message to aid in debugging. The message is not meant to be displayable to end-users, nor it is meant to be machine-readable. It should be seen as something that the client would log to assist in debugging, but it's never meant to be in any way parsed by the client.
## Supported Browsers & Devices
required in the API Docs, as additional data allows Tabby to increase the AOVs and conversion approval rates.
### Eligibility Check
As a response you receive one of the two session statuses - "created" or "rejected":
* if the session status is "created" - save the **id of the session** (will be required for cancellation step) and **payment.id** (will be required for payment status check and refund steps) received in the response:
```
"status": "created"
"id": "string" // ID of the session
"payment"."id":"string" // ID of the payment
```
* if the session status is "rejected" - show the Payment failure screen and offer the customer an alternative payment method.
"rejection\_reason" field can take the following values, you may optionally add human readable messages for cashier:
| Reason | English | Arabic |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `not_available` | Sorry, Tabby is unable to approve this purchase. Please use an alternative payment method for your order. | نأسف، تابي غير قادرة على الموافقة على هذه العملية. الرجاء استخدام طريقة دفع أخرى. |
| `order_amount_too_high` | This purchase is above your current spending limit with Tabby, try a smaller cart or use another payment method | قيمة الطلب تفوق الحد الأقصى المسموح به حاليًا مع تابي. يُرجى تخفيض قيمة السلة أو استخدام وسيلة دفع أخرى. |
| `order_amount_too_low` | The purchase amount is below the minimum amount required to use Tabby, try adding more items or use another payment method | قيمة الطلب أقل من الحد الأدنى المطلوب لاستخدام خدمة تابي. يُرجى زيادة قيمة الطلب أو استخدام وسيلة دفع أخرى. |
## Customer payment options
* **First option: Send the Payment Link** to the customer via SMS using **send\_hpp\_link API** (provided in a Postman Collection). You can use this method only if you receive a "created" status in the response to the previous request.
* **Second option: use the POS QR Code integration** as a fallback option.
## Payment Processing
Verify the payment status using:
* Webhooks
* or Retrieve Payment API call
### Webhooks
* Tabby sends you a notification payment status update. The initial payment status is CREATED.
* If the Webhook with the authorized or closed status is received - mark the order as successful in your OMS. You can ignore other Webhooks received for this payment.id.
* If the Webhook returns a rejected status - mark the payment as unsuccessful and ask the customer to pay with another payment method.
* If no status is received - the cashier should have an option to cancel the payment.CREATED - the payment has not been completed yet, wait for it to change to one of the terminal statuses.
* AUTHORIZED or CLOSED - a payment was placed successfully, mark orders as successful and proceed with the order on your POS/OMS.
* REJECTED or EXPIRED - a payment is not successful. Ask the customer to pay with a different payment method.
authorized, while Retrieve Request - in upper case: AUTHORIZED.
CREATED. Once canceled - the status will change to EXPIRED.
If the payment has already been authorized, attempting to cancel it will return the following error: 400 Bad Request
```JSON theme={"dark"}
{
"status": "error",
"errorType": "bad_data",
"error": "session is finalized"
}
```
In this case check the payment status via the Retrieve Payment API call and verify the status is AUTHORIZED or CLOSED. Then show a success screen, print a receipt and proceed with the order.
AUTHORIZED, CLOSED, REJECTED or EXPIRED - the session cannot be cancelled.
payment.id by matched payment.order.reference\_id in your OMS.
You can also process a refund from the Tabby Merchant Dashboard.
CLOSED with a captured amount present in the "captures":\[] array of objects can be refunded.CAPTURED.*
OTP:8888 on Tabby Checkout Page.
6. Verify that the successful payment status is received.
**Expected Results:**
1. Session creation response has status "created" - the customer is eligible to use Tabby.
2. A payment link is successfully sent as an SMS to the customer and Tabby Checkout Page opened.
3. Credentials are entered.
4. The success Tabby screen appears.
5. Payment is successful and captured:
* on Merchant Dashboard payment status is CAPTURED
* via a Retrieve Payment API call response Payment status is CLOSED, captured amount is present in the "captures":\[] array of objects.
NEW on the Merchant Dashboard or AUTHORIZED via Retrieve Payment API call - kindly contact your Tabby Account manager or `partner@tabby.ai` / `partner@tabby.sa` to update auto-capture settings.
"rejected" - the customer is **not** eligible to use Tabby.
* **Optionally**: one of the rejection reasons can be shown to cashier.
### 3. Payment Cancellation
**Testing Steps:**
1. From a Cashier's POS choose Tabby.
2. Enter payment amount and a real phone number to receive the real payment link.
"created" - the customer is eligible to use Tabby.
2. A payment link is successfully sent as an SMS to the customer, Tabby Checkout Page opens.
3. A session is cancelled.
4. On checking Payment Status via Retrieve Payment API call it should be EXPIRED.
"EXPIRED" after **session expiry timeout + 5 minutes** (20 + 5 by default). After that the payment will remain in status "EXPIRED", no need to check it further.
OTP:8888 on Tabby Checkout Page.
6. Verify the payment status via Retrieve Payment API.
**Expected Results:**
1. Session creation response has status "created" - the customer is eligible to use Tabby.
2. A payment link is successfully sent as an SMS to the customer.
3. Tabby Checkout Page opens, credentials are entered.
4. The rejection screen with the message 'We can't approve this purchase' appears.
5. On checking Payment Status via Retrieve Payment API call it should be REJECTED.
## Postman Collection
1. Download the JSON file and import it into Postman.
2. Set your base\_url, secret\_key, merchant\_code, and currency in Collection Variables. See Base URLs for regional domains.
"created" or "rejected":
* if the session status is "created" - save the **id of the session** (will be required for cancellation step) and **payment.id** (will be required for payment status check and refund steps) received in the response:
```
"status": "created"
"id": "string" // ID of the session
"payment"."id":"string" // ID of the payment
"configuration"."available_products.installments[0].qr_code": "string" // QR code link which you can use to get the image of the QR code and show it on the POS screen
"configuration"."available_products.installments[0].web_url": "string" // Session link, if you want to use it to generate your own QR code
```
* if the session status is "rejected" - show the Payment failure screen and offer the customer an alternative payment method. Please, do not proceed with any further steps with Tabby. The rejection might be related to order amount being too high, disabled branch code, or other reasons. The response payload will contain the following:
```
"status": "rejected"
```
## Show QR Code
When the session has status "created" you will receive two links in the response. Use either of them to show the QR Code on the POS screen:
| **Response field** | **What it returns** | **When to use** |
| ---------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `configuration.available_products.installments[0].qr_code` | A link to a **ready-to-display QR code image** (PNG, 200×200 px) | **Recommended.** Fetch the image with a plain HTTP GET and render it directly on the POS screen — no QR generation library is required |
| `configuration.available_products.installments[0].web_url` | The Tabby Checkout session link | Generate your own QR code from this link if you need a custom size or design |
### Using the Ready-Made QR Image
The qr\_code link points to the GET /api/v2/checkout/\{id of session}/hpp\_link\_qr endpoint, which responds with a black-and-white PNG image (Content-Type: image/png, 200×200 px, under 1 KB):
* Use the link **exactly as returned** in the session response — do not construct or modify it manually, all required query parameters are already included.
* The request requires **no authentication headers**, so the POS application can fetch the image directly, without proxying it through your backend.
* Render the PNG in a native image component (for example, an ImageView on Android-based POS terminals) — no WebView or browser is needed.
### QR Code Display Recommendations
* **Size.** Display the QR code at least **3×3 cm** on the physical screen. When upscaling the 200×200 px image, use integer scale factors with nearest-neighbor (non-smoothing) scaling so the QR modules stay sharp. If your framework only supports smooth scaling, generate your own QR code from web\_url at the native resolution instead.
* **One code per payment.** The QR code is unique for each payment session. Never cache or reuse the image between payments — fetch a fresh one for every new session.
* **Fallback.** If the image fails to load (for example, due to a network error), create a new payment session and show the QR code from the qr\_code link of the new response.
## Payment Processing
Once QR Code is shown, check the payment status using the Retrieve Payment API call. We recommend calling the Retrieve API **every 5 seconds** until a terminal status is received. Alternatively, you can add a **“Check status”** button on the POS terminal to manually check this.
The following statuses can be received:
* CREATED - the payment has not been completed yet, wait for it to change to one of the terminal statuses.
* AUTHORIZED or CLOSED - the payment is successful, mark order as successful, print a receipt.
* REJECTED or EXPIRED - the payment is not successful. Ask the customer to pay with a different payment method.
### Cancel a Payment
A request to cancel a payment is available in the Postman collection.
You can cancel a payment in two cases:
1. The cashier presses the “Cancel” button on the POS.
2. Automatically, after a timeout. The **recommended** period is **300 seconds**, but the timeout should **never be less than 180 seconds**.
The payment can only be canceled if its status is CREATED. Once canceled - the status will change to EXPIRED.
If the payment has already been successful, attempting to cancel it will return the following error: 400 Bad Request
```JSON theme={"dark"}
{
"status": "error",
"errorType": "bad_data",
"error": "session is finalized"
}
```
In this case check the payment status via the Retrieve Payment API call and verify the status is AUTHORIZED or CLOSED. Then show a success screen, print a receipt and proceed with the order.
AUTHORIZED, CLOSED, REJECTED or EXPIRED - the session cannot be cancelled.
payment.id by matched payment.order.reference\_id in your OMS.
You can also process a refund from the Tabby Merchant Dashboard.
CLOSED with a captured amount present in the "captures":\[] array of objects can be refunded.CAPTURED.*
Native Screen POS Journey
OTP:8888 on Tabby Checkout page.
5. Verify that the successful status is received.
**Expected Results:**
1. Session creation response has status "created", and a QR code is shown successfully on the POS screen.
2. Tabby Checkout Page opens from the QR code.
3. Credentials are entered.
4. The success Tabby screen appears.
5. Payment is successful and captured:
* on Merchant Dashboard payment status is CAPTURED
* via a Retrieve Payment API call response Payment status is CLOSED, captured amount is present in the "captures":\[] array of objects.
NEW on the Merchant Dashboard or AUTHORIZED via Retrieve Payment API call - kindly contact your Tabby Account manager or `partner@tabby.ai` / `partner@tabby.sa` to update auto-capture settings.
4xx or 5xx status code.
* **Incomplete response** - session is received but configuration.available\_products.installments\[0].qr\_code and web\_url are not present.
3. Observe POS behavior while the terminal attempts to create the session and display a QR code.
4. Select an alternative payment method on the POS terminal to complete the order.
**Expected Results:**
1. Tabby is present among payment methods on the POS terminal.
2. Session creation does not complete successfully - the POS receives no response, an error status, or an incomplete payload.
3. No QR code is shown; a failure screen or error message is displayed to the cashier, prompting to retry or select an alternative payment method. No payment is created in Tabby.
4. The order can be completed via another payment method on the POS terminal.
### 3. Payment Cancellation
**Testing Steps:**
1. Choose Tabby on the POS terminal and enter the payment amount.
2. Show the QR code on the POS terminal for the customer to scan.
3. Click cancel (Cross icon) on Tabby Checkout page (you may also cancel the session from your POS terminal).
**Expected Results:**
1. Tabby is present among payment methods on POS terminal.
2. Session creation response has status "created", and a QR code is shown successfully on the POS screen.
3. Tabby Checkout Page opens, a session is cancelled. On checking Payment Status via Retrieve Payment API call it should be EXPIRED status. A new session can be created from POS terminal.
OTP:8888 on Tabby Checkout page.
5. Verify the payment status via Retrieve Payment API.
**Expected Results:**
1. Tabby is present among payment methods on POS terminal.
2. Session creation response has status "created", and a QR code is shown successfully on the POS screen.
3. Tabby Checkout Page opens, credentials are entered.
4. The rejection screen with the message 'We can’t approve this purchase' appears.
5. On checking Payment Status via Retrieve Payment API call it should be REJECTED.
## Postman Collection
1. Download the JSON file and import it into Postman.
2. Set your base\_url, secret\_key, merchant\_code, and currency in Collection Variables. See Base URLs for regional domains.
Show rejection message for ineligible customers
"payment"."id" **from the response** - it will be used to verify, capture and refund the payment on the next steps.
"lang", enum "ar" / "en"
* **Session creation request** contains all the required parameters from Tabby API
* Success scenario is working
* Cancellation scenario is working
* Failure scenario is working
* Corner case is supported
## Payment Verification and Processing
* Webhooks are registered for each `merchant_code` + secret key pair (up to 4 webhooks per pair). To receive webhooks for test payments, register them with your test key (`sk_test_...`)
* After a payment is placed successfully with Tabby you receive a webhook to your registered url with status "authorized"
* On receiving it you should **trigger a** getPayment request to verify the status of the payment
* If a status is "AUTHORIZED" - a capture request should be triggered from your side
* It is an expected behaviour that webhooks return "authorized" in lower case while getPayment - in upper case: "AUTHORIZED".
* A **full amount** must be captured
If you have any questions considering this Checklist - feel free to contact us in the Integrations thread.
# App Promo Messaging
Source: https://docs.tabby.ai/pay-in-4-custom-integration/mobile-apps/app-promo-messaging
Promo messaging in mobile apps: SDK snippet components, or custom snippets with the standard copy and Tabby pop-up URLs.
Tabby SDKs contain ready-made snippet components for the Product, Cart, and Checkout pages of your app.
## Custom Promo Snippets
If you build your own promo components instead, use the standard Tabby copy and open the Tabby "Learn more" pop-up in a webview.
This page describes the installation process for Tabby Catalogue in Shopify.
Shopify Product Catalogue in Dashboard
App Permissions
Connection Step
Key Installation
Publishing Step
Here you will find the instruction how to install Tabby Catalogue in Zid.
Make sure your store is published before uploading the items
Tabby Catalogue in Zid App Market
Activation Page
base\_url — `https://api.tabby.ai` (UAE, Kuwait) or `https://api.tabby.sa` (KSA). See Base URLs.
* secret\_key — your Tabby Secret API Key
* merchant\_code — your merchant code
* currency — `AED`, `SAR`, or `KWD`
OTP:8888 on Tabby HPP and redirect to the store's success page.
5. Verify that the capture of the successful payment occurred - check for status CAPTURED on the Merchant Dashboard or Payment status AUTHORIZED and CLOSED via Retrieve Payment API.
**Expected Results:**
1. Store checkout opens.
2. Tabby payment method is available on the checkout page (background pre-scoring passed successfully).
3. Tabby Hosted Payment Page opens.
4. The success Tabby screen appears and redirects to the Success URL; the store's 'Thank you' page appears.
5. Order is captured:
* Payment Status is CLOSED;
* captured amount is present in the "captures":\[] array of objects.
## 2. Background Pre-scoring Reject
**Testing Steps:**
1. Add an item to your shopping cart and proceed to checkout.
2. Fill in all the required fields at checkout, and use the following email and phone numbers:
```
Background Pre-scoring reject flow:
UAE: otp.success@tabby.ai, phone: +971500000002
KSA: otp.success@tabby.ai, phone: +966500000002
Kuwait: otp.success@tabby.ai, phone: +96590000002
```
3. Attempt to choose Tabby as the payment method.
**Expected Results:**
1. Store checkout opens.
2. Tabby payment method is hidden or marked as unavailable with the message:
* English: Sorry, Tabby is unable to approve this purchase, please use an alternative payment method for your order.
* Arabic: نأسف، تابي غير قادرة على الموافقة على هذه العملية. الرجاء استخدام طريقة دفع أخرى.
3. Tabby is hidden from the payment methods list or marked as unavailable.
## 3. Payment Cancellation
**Testing Steps:**
1. Add an item to your shopping cart and proceed to checkout.
2. Fill in all the required fields at checkout, and use the following email and phone numbers:
```
Positive flow:
UAE: otp.success@tabby.ai, phone: +971500000001
KSA: otp.success@tabby.ai, phone: +966500000001
Kuwait: otp.success@tabby.ai, phone: +96590000001
```
3. Choose Tabby as the payment method and click "Place order."
4. Click on the 'Back to Store' button (Desktop) or the left corner cross button (Mobile), and confirm cancellation.
**Expected Results:**
1. Store checkout opens.
2. Tabby payment method is available on the checkout page (background pre-scoring passed successfully).
3. Tabby Hosted Payment Page opens.
4. Redirect to the Cancel URL - store checkout or cart page. Verify that the cart is not emptied, and a text message with a cancellation reason is shown:
* English: You aborted the payment. Please retry or choose another payment method.
* Arabic: لقد ألغيت الدفعة. فضلاً حاول مجددًا أو اختر طريقة دفع أخرى.
## 4. Payment Failure
**Testing Steps:**
1. Add an item to your shopping cart and proceed to checkout.
2. Fill in all the required fields at checkout, and use the following email and phone numbers:
```
Negative flow:
UAE: otp.rejected@tabby.ai, phone: +971500000001
KSA: otp.rejected@tabby.ai, phone: +966500000001
Kuwait: otp.rejected@tabby.ai, phone: +96590000001
```
3. Choose Tabby as the payment method and click "Place order."
4. Finish the payment using OTP:8888 in Tabby HPP.
5. Confirm returning to the store by clicking the 'Back to store' button.
6. Verify the payment status via Retrieve Payment API.
**Expected Results:**
1. Store checkout opens.
2. Tabby payment method is available on the checkout page (background pre-scoring passed successfully).
3. Tabby Hosted Payment Page opens.
4. The rejection screen with the message 'We can’t approve this purchase' appears.
5. Redirect to the Failure URL - store checkout or cart page. Verify that the cart is not emptied, and a text message with a failure reason is shown:
* English: Sorry, Tabby is unable to approve this purchase, please use an alternative payment method for your order.
* Arabic: نأسف، تابي غير قادرة على الموافقة على هذه العملية. الرجاء استخدام طريقة دفع أخرى.
6. Tabby payment method is still available for selection among payment methods on Checkout.
7. No order appears in the Merchant Dashboard (unsuccessful orders are not displayed in the Dashboard), Payment Status REJECTED.
## 5. Corner Case
**Testing Steps:**
1. Add an item to your shopping cart and proceed to checkout.
2. Fill in all the required fields at checkout, and use the following email and phone numbers:
```
Negative flow:
UAE: otp.success@tabby.ai, phone: +971500000001
KSA: otp.success@tabby.ai, phone: +966500000001
Kuwait: otp.success@tabby.ai, phone: +96590000001
```
3. Choose Tabby as the payment method and click "Place order."
4. Finish the payment using OTP:8888 in Tabby HPP.
5. Once you see the Success Tabby screen (with the tick), **close the browser tab before the redirection.**
6. Verify that the **capture** of the successful payment occurred - check **order status CAPTURED on the Merchant Dashboard** or Payment status via Retrieve Payment API is CLOSED. Ensure the order is marked **successful** on your side.
**Expected Results:**
1. Store checkout opens.
2. Tabby payment method is available on the checkout page (background pre-scoring passed successfully).
3. Tabby Hosted Payment Page opens.
4. There is no redirection to the Success page as the browser tab is closed before redirection.
5. Payment Status changes to AUTHORIZED, then after capture is triggered, it changes to CLOSED with a captured amount in the "captures":\[] array of objects, triggered by the Webhook notifications or Cron Job.AUTHORIZED **before capture** and CLOSED **after capture**.
AUTHORIZED status on Payments API or NEW status on Merchant Dashboard), you can initiate a **Manual Capture** or **Cancel** on the Merchant Dashboard, or **Capture** or **Close** Payment API Request.
CLOSED with the refunded amount in the refunds":\[] array of objects.
## 7. Tabby Checkout Focus Change (Mobile Apps)
**Precondition:** Tabby Checkout is opened using positive flow credentials at the OTP step.
**Testing Steps:**
1. At the OTP step on Tabby Checkout opened in the Webview/In-App browser, minimize the app by navigating to the home screen.
2. Wait a few seconds and then return to the app.
**Expected Results:**
1. The app correctly recovers the Tabby checkout screen at the same step. No crashes or hangs of the app after the return.
2. No App or Webview issues appear.