# Tabby for Unified Payments API
> **Note**
>
> We no longer support new Tabby integrations on the Payments API. For new Tabby integrations, use the [Payment Setup API](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-using-the-payment-setup-api.md).
To accept Tabby payments, follow these steps:
1. [Request a payment context](#Request_a_payment_context).
2. [Request a payment](#Request_a_payment).
If you used a manual capture flow, you must also [capture the payment](#Manually_capture_the_payment_).
## Request a payment context
To check if Tabby is available for a purchase, call the [Request a payment context](https://api-reference.checkout.com/tag/Payment-Context/#operation/requestAPaymentContext) endpoint:
**Live**
`POST` `https://{prefix}.api.checkout.com/payment-contexts`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payment-contexts`
> **Information**
>
> The Payment Contexts API supports [idempotency](https://www.checkout.com/docs/developer-resources/api/idempotency.md). You can safely retry API requests without the risk of duplicate requests.
### Request example
```json
{
"source": {
"type": "tabby"
},
"amount": 10000,
"currency": "AED",
"customer": {
"email": "johnsmith@example.com",
"name": "John Smith",
"phone": {
"country_code": "971",
"number": "500000001"
}
},
"processing": {
"locale": "ar-AE"
},
"processing_channel_id": "{{tabby-processing-channel-id}}",
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
}
```
For a better acceptance rate, ensure you include:
- The `reference` field
- The `items[]` object in your payment context request, along with the `shipping[]` object if `items.type` is set to `physical`
- As many details as you can in the `customer` object
Tabby performs a credit assessment on each customer as they go through the sign up and checkout process. For more information, see the [Risk assessment](#Risk_assessment) section.
For the full API specification, see the [API reference](https://api-reference.checkout.com/tag/Payments/#operation/requestAPaymentOrPayout).
### Response example
If your request is successful, you receive a `201 Created` response code and you can offer Tabby as a payment method for this purchase.
A successful request contains the `available_payment_types` field:
```json
{
"id": "pct_y3oqhf46pyzuxjbcn2giaqnb44",
"available_payment_types": [
{
"payment_type": "Installment"
}
],
"_links": {
"self": "https://{prefix}.api.checkout.com/payment-contexts/pct_y3oqhf46pyzuxjbcn2giaqnb44" }
}
```
If you receive a `201 Created` response code with the `unavailable_payment_types` field, you cannot offer Tabby as payment method for this purchase:
```json
{
"id": "pct_y3oqhf46pyzuxjbcn2giaqnb44",
"unavailable_payment_types": [
{
"payment_type": "installment",
"rejection_reason": "order_amount_too_low"
}
],
"_links": {
"self": "https://{prefix}.api.checkout.com/payment-contexts/pct_y3oqhf46pyzuxjbcn2giaqnb44" }
}
```
## Request a payment
When the customer selects Tabby and requests to pay, call the [Request a payment](https://api-reference.checkout.com/tag/Payments/#operation/requestAPaymentOrPayout) endpoint:
**Live**
`POST` `https://{prefix}.api.checkout.com/payments`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments`
### Request example
```json
{
"payment_context_id": "pct_xxx",
"payment_type": "Installment",
"processing_channel_id": "{{processing_channel_id}}"
}
```
Ensure you include the `items[]` object and the `reference` field if you did not provide it in your payment context request. Additionally, you must include the `shipping[]` object if all `items[].type` fields are set to `physical`.
### Response example
If your request is successful, you receive a `202 Success` response code with a `status` field set to `Pending`.
```json
{
"id": "pay_mbabizu24mvu3mela5njyhpit4",
"status": "Pending",
"reference": "ORD-5023-4E89",
"customer": {
"id": "cus_y3oqhf46pyzuxjbcn2giaqnb44",
"email": "johnsmith@example.com",
"name": "John Smith",
"phone": {
"country_code": "1",
"number": "415 555 2671"
}
},
"_links": {
"self": {
"href": "https://{prefix}.api.checkout.com/payments/pay_mbabizu24mvu3mela5njyhpit4"
},
"redirect": {
"href": "https://checkout.tabby.ai/?sessionId=ad76fb0e-3b52-4c8f-85d3-5171d84e5b6b&apiKey=pk_test_e7522500-ea7b-44d4-9f76-22b3ef8167b7&product=installments&merchantCode=CKOAED"
}
}
}
```
If the customer has a Tabby account, they get a one-time password (OTP) to authenticate. If the customer doesn't have an account, they are redirected to sign up for an account in Tabby's end.
> **Information**
>
> The sign up option is only available in the production environment.
## Manually capture the payment `Optional`
A successful authorization places a hold on the customer's funds. With the manual capture flow, you can capture the funds at a later point in time. For example, if you need to verify that the item the customer purchased is still in stock.
> **Note**
>
> Trigger the manual capture when you ship the items.
If you are using the gateway processing model, Checkout.com can capture the full amount for the payment or perform multiple partial captures. For partial captures, include information about the items in the `items[]` object.
- If the capture amount is equal to the authorized amount, we consider the capture full and final.
- If the capture amount is less than the authorized amount and your capture request:
- Includes `"capture_type": "Non-Final"`, we do not release the remaining authorized amount
- Does not include `"capture_type"`, or includes `"capture_type": "Final"`, we release the remaining authorized amount
> **Note**
>
> If you use the collecting processing model, multiple partial captures are not supported. Any partial capture is considered final and we release the remaining authorized amount.
For more information on capturing payments, see [Capture a payment](https://www.checkout.com/docs/payments/manage-payments/capture-a-payment.md).
### Partial capture with items
If you want to capture part of the amount, we recommend including information about the items in the `items[]` object.
Additionally, you can include processing information such as discount and tax amounts in the `processing` object.
**Live**
`POST` `https://{prefix}.api.checkout.com/payments/{id}/captures`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/{id}/captures`
#### Request example
```json
{
"amount": 5000,
"capture_type": "NonFinal",
"items": [
{
"name": "jumper",
"quantity": 1,
"unit_price": 6000,
"reference": "858818ac",
"type": "physical",
"discount_amount": 1000,
"url": "string",
"image_url": "string"
}
],
"processing": {
"shipping_amount": 200,
"tax_amount": 100,
"discount_amount": 1000
}
}
```
#### Response example
If your request is successful, you receive a `202 Success` response code and the `action_id`.
```json
{
"action_id": "act_y3oqhf46pyzuxjbcn2giaqnb44",
"_links": {
"payment": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_y3oqhf46pyzuxjbcn2giaqnb44"
}
}
}
```
### Multiple partial capture
If you want to perform multiple partial captures, include `"capture_type": "NonFinal"` in your request.
**Live**
`POST` `https://{prefix}.api.checkout.com/payments/{id}/captures`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/{id}/captures`
#### Request example
```json
{
"amount": 1000,
"capture_type": "NonFinal"
}
```
#### Response example
If your response is successful, you receive a `202 Success` response code and an `action_id`.
```json
{
"action_id": "act_y3oqhf46pyzuxjbcn2giaqnb44",
"_links": {
"payment": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_y3oqhf46pyzuxjbcn2giaqnb44"
}
}
}
```
### Full capture
If you want to capture the full amount, call the [Capture a payment](https://api-reference.checkout.com/tag/Payments/#operation/captureAPayment) endpoint, and provide the `payment_id` as the `{id}` path parameter.
**Live**
`POST` `https://{prefix}.api.checkout.com//payments/{id}/captures`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/{id}/captures`
#### Response example
If your request is successful, you receive a `202 Success` response code.
```json
{
"action_id": "act_y3oqhf46pyzuxjbcn2giaqnb44",
"_links": {
"payment": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_y3oqhf46pyzuxjbcn2giaqnb44"
}
}
}
```
---
## Get details about a payment
To retrieve details about the payment, call the [Get payment details](https://api-reference.checkout.com/tag/Payments/#operation/getPaymentsList) endpoint, and provide the `{id}` path parameter using the `payment_id` value you received in the `Create a payment` response.
---
## Refund a payment
Tabby supports both partial and full refunds.
You can only refund manually captured payments if:
- You performed a final capture.
- The payment was voided after a partial or non-final capture.
For more information, see [Refund a payment](https://www.checkout.com/docs/payments/manage-payments/refund-a-payment.md).
Call the [Refund a payment](https://api-reference.checkout.com/tag/Payments/#operation/refundAPayment) endpoint, and provide the payment `id` as a path parameter.
**Live**
`POST` `https://{prefix}.api.checkout.com/payments/{id}/refunds`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/{id}/refunds`
### Request example
```json
{
"amount": 100
}
```
### Response example
```json
{
"actionId": "act_cxpffngdvouvabegyy3asiuou",
"_links": {
"payment": {
"href": "https://{prefix}.api.checkout.com/payments/pay_ok7yhvutuylevnatk3x3dxviq4"
}
}
}
```
### Partial refund with items
For a partial refund, ensure you include information about the items in the `items[]` object.
You cannot perform a partial refund if the capture is not final.
Call the [Refund a payment](https://api-reference.checkout.com/tag/Payments/#operation/refundAPayment) endpoint, and provide the payment `id` as a path parameter.
**Live**
`POST` `https://{prefix}.api.checkout.com/payments/{id}/refunds`
**Sandbox**
`POST` `https://{prefix}.api.sandbox.checkout.com/payments/{id}/refunds`
#### Request example
```json
{
"amount": 5000,
"items": [
{
"name": "jumper",
"quantity": 1,
"unit_price": 5000,
"reference": "858818ac",
"type": "physical",
"discount_amount": 0,
"url": "string",
"image_url": "string"
}
]
}
```
#### Response example
If your request is successful, you receive a `202 Success` response code and the `action_id`.
```json
{
"action_id": "act_y3oqhf46pyzuxjbcn2giaqnb44",
"_links": {
"payment": {
"href": "https://{prefix}.api.sandbox.checkout.com/payments/pay_y3oqhf46pyzuxjbcn2giaqnb44"
}
}
}
```
---
## Cancel or void a payment
### Cancel a payment with auto capture
Once you create a payment using the auto-capture payment flow, you cannot void it. If you want to reverse a payment that is in progress, wait until you receive the `payment_captured` webhook, and then process a refund.
### Void payment for manual captured payment flow
You can void a payment after it is authorized but not yet captured.
For more information, see the [Void a payment](https://www.checkout.com/docs/payments/manage-payments/void-a-payment) page.
---
## Optional features
Optional features include:
* Risk assessment
* Travel industry data
### Risk assessment
Tabby performs a credit assessment on each customer as they go through the sign up and checkout process.
To ensure a better acceptance rate, ensure you provide as many fields as possible in the `customer` object when requesting the payment context:
- `customer.email`
- `customer.email_verified`
- `customer.name`
- `customer.phone`
- `customer.phone.country_code`
- `customer.phone.number`
- `customer.phone.phone_verified`
##### Request example
```json
{
"source": {
"type": "tabby"
},
"amount": 6540,
"currency": "AED",
"capture": true,
"reference": "ORD-5023-4E89",
"description": "Set of 3 masks",
"customer": {
"email": "johnsmith@example.com",
"email_verified": true,
"name": "John Smith",
"phone": {
"country_code": "1",
"number": "415 555 2671",
"phone_verified": true
},
"summary": {
"registration_date": "2021-08-24",
"total_order_count": 10,
"first_transaction_date": "2022-06-24",
"last_payment_date": "2024-06-15",
"last_payment_amount": 300
},
"shipping": {
"address": {
"address_line1": "123 High St.",
"city": "London",
"zip": "SW1A 1AA"
}
},
"processing": {
"shipping_amount": 300,
"discount_amount": 100,
"tax_amount": 3000,
"locale": "ar"
}
},
"items": [
{
"type": "Physical",
"name": "Test item",
"quantity": 2,
"unit_price": 50,
"reference": "858818ac",
"discount_amount": 1000,
"url": "string",
"image_url": "string"
}
],
"processing_channel_id": "{{processing_channel_id}}",
"success_url": "https://example.com/payments/success",
"failure_url": "https://example.com/payments/failure"
}
```
### Travel industry data
If you're in the travel sector, provide the `processing.airline_data[]` or `processing.accommodation_data[]` objects whenever possible in your payment context or payment request:
#### Airline data
```json
{
"processing": {
"airline_data": [
{
"ticket": {
"number": "045-21351455613"
},
"passenger": [
{
"first_name": "John",
"last_name": "White",
"date_of_birth": "1990-05-26"
}
],
"flight_leg_details": [
{
"travel_class": "Economy",
"carrier_code": "BA",
"departure_date": "2023-06-19",
"departure_airport": "LHR",
"arrival_airport": "LAX"
},
{
"travel_class": "Economy",
"carrier_code": "BA",
"departure_date": "2023-06-23",
"departure_airport": "LAX",
"departure_time": "15:30",
"arrival_airport": "LHR"
}
]
}
]
}
}
```
#### Accommodation data
```json
{
"processing": {
"accommodation_data": [
{
"booking_reference": "ABC123",
"name": "Jim's Hotel",
"address": {
"address_line1": "39 Hercules St",
"city": "Brisbane",
"country": "AU"
},
"check_in_date": "2024-05-20",
"check_out_date": "2024-05-20",
"guests": [
{
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1990-05-20"
}
],
"number_of_rooms": 1
}
]
}
}
```
---
## Test your integration
To activate Tabby payments in the sandbox environment and start testing, contact your account manager, integrations engineer, or [request support](https://dashboard.checkout.com/support/new?topic=case_account_management_and_access&issue=issue_account_changes).
Follow the Tabby payment flow to create a payment, using either auto capture or manual capture.
Finish the payment in the Tabby hosted payment page, using the following sample data:
- OTP – `8888`
- Card – `4111111111111111`
- Expiration date – `12/30`
- CVV – `123`
For more detailed testing instructions, see [Tabby testing credentials](https://docs.tabby.ai/testing-guidelines/testing-credentials).
---
## Move your integration to the production environment
To activate Tabby payments in the production environment, contact your account manager, integrations engineer, or [request support](https://dashboard.checkout.com/support/new?topic=case_account_management_and_access&issue=issue_account_changes).