Linkit

Providers Paylinks API

Unified payment link management across all BNPL and direct payment providers

Unified Providers Paylinks API

A single, provider-agnostic API for creating and managing BNPL payment links (Tabby, Tamara, MisPay). GET /api/v1/providers also lists gateway sync processors (stripe, moyasar, tap, dinero, paypal, hyperpay); those IDs are not valid for POST .../paylinks — use Payments Orders or schedule the mapped integration app instead.

All endpoints require authentication via Bearer token. The provider field in create requests determines which payment provider to use.


Supported Providers

ProviderTypeCheckout / roleRegions
tabbybnplQR code paylinksKSA, UAE, Kuwait
tamarabnplSMS paylinksKSA, UAE, Bahrain
mispaybnplQR code paylinksKSA
stripegateway_syncStripe PaymentIntents sync (stripe-payments)Global (account)
moyasargateway_syncMoyasar payments sync (moyasar-payments)MENA
tapgateway_syncTap charges list sync (tap-payments)GCC / Tap markets
dinerogateway_syncDinero status refresh (dinero-payments)KSA / Dinero markets
paypalgateway_syncPayPal reporting sync (paypal-commerce)Global (account)
hyperpaygateway_syncOPPWA query sync (hyperpay-checkout)Per acquirer / host

List Providers

Returns all registered payment providers and their metadata.

GET /api/v1/providers
Authorization: Bearer <token>

Response

Each entry includes id, name, description, type, regions, and when applicable app_slug (integration app used by Payments Orders).

{
  "providers": [
    {
      "id": "dinero",
      "name": "Dinero Pay",
      "description": "Dinero Pay: refresh configured payment_ids…",
      "type": "gateway_sync",
      "regions": "KSA and supported Dinero markets",
      "app_slug": "dinero-payments"
    },
    {
      "id": "mispay",
      "name": "MisPay",
      "description": "Split-in-4 BNPL with QR code checkout for POS",
      "type": "bnpl",
      "regions": "KSA",
      "app_slug": "mispay-pos-paylinks"
    }
  ],
  "total": 9
}

Provider Configuration

Returns provider-specific configuration, required fields, and endpoint documentation.

GET /api/v1/providers/config/{provider}
Authorization: Bearer <token>

Creates a BNPL payment link using the specified provider.

POST /api/v1/providers/paylinks
Authorization: Bearer <token>
Content-Type: application/json

Common Fields

FieldTypeRequiredDescription
providerstringBNPL provider ID only: tabby, tamara, mispay (not stripe / moyasar / tap / dinero)
org_app_idstringOrganization app ID for the installed provider app
order_idstringYour order reference ID
amountstring/numberPayment amount (e.g. "100.00")
currencystringCurrency code (SAR, AED, KWD)
descriptionstringOrder description
buyer_namestringCustomer name
buyer_emailstringCustomer email
buyer_phonestringCustomer phone
langstringCheckout language (ar or en)
itemsarrayLine items
metadataobjectProvider-specific metadata

Provider-Specific Fields

Tamara

FieldTypeDescription
phone_numberstringRequired. Customer phone for SMS checkout
payment_typestringpay_by_instalments (default) or pay_by_later
store_codestringStore identifier for multi-store setups
localestringLocale for checkout page (defaults to ar_SA)

Example — Tabby

curl -X POST "https://linkit.works/api/v1/providers/paylinks" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "tabby",
    "org_app_id": "YOUR_ORG_APP_ID",
    "order_id": "POS-1234",
    "amount": "150.00",
    "currency": "SAR",
    "description": "In-store purchase",
    "buyer_phone": "0500000001"
  }'
const res = await fetch('https://linkit.works/api/v1/providers/paylinks', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    provider: 'tabby',
    org_app_id: 'YOUR_ORG_APP_ID',
    order_id: 'POS-1234',
    amount: '150.00',
    currency: 'SAR',
    description: 'In-store purchase',
    buyer_phone: '0500000001',
  }),
});
const data = await res.json();
// data.checkout_url → redirect customer
// data.qr_code_url → display QR to customer

Response (201 Created)

{
  "success": true,
  "provider": "tabby",
  "paylink_id": "abc123",
  "session_id": "sess_xxxxx",
  "payment_id": "pay_xxxxx",
  "checkout_url": "https://checkout.tabby.sa/...",
  "qr_code_url": "https://checkout.tabby.sa/qr/...",
  "status": "created",
  "order_id": "POS-1234"
}

Example — Tamara

curl -X POST "https://linkit.works/api/v1/providers/paylinks" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "tamara",
    "org_app_id": "YOUR_ORG_APP_ID",
    "order_id": "POS-5678",
    "amount": "200.00",
    "currency": "SAR",
    "phone_number": "+966500000001"
  }'

GET /api/v1/providers/paylinks/{id}
Authorization: Bearer <token>

Retrieves the current status of a payment link. Automatically refreshes status from the provider API when possible.

Response

{
  "id": "abc123",
  "provider": "tabby",
  "org_app_id": "...",
  "order_id": "POS-1234",
  "status": "authorized",
  "amount": "150.00",
  "currency": "SAR",
  "checkout_url": "https://checkout.tabby.sa/...",
  "qr_code_url": "https://checkout.tabby.sa/qr/..."
}

GET /api/v1/providers/paylinks?provider=tabby&org_app_id=YOUR_ORG_APP_ID
Authorization: Bearer <token>

Optional query parameters:

  • provider — Filter by provider (e.g. tabby, tamara, mispay)
  • org_app_id — Filter by organization app

Capture/Finalize Payment

Captures (Tabby/Tamara) or finalizes (MisPay) a payment. Call this after the customer has completed checkout.

POST /api/v1/providers/paylinks/{id}/capture
Authorization: Bearer <token>
Content-Type: application/json

Optional Body

FieldTypeDescription
amountstringCapture amount (defaults to full order amount)
reference_idstringIdempotency key for the capture

Response

{
  "success": true,
  "provider": "tabby",
  "paylink_id": "abc123",
  "payment_id": "pay_xxxxx",
  "status": "CLOSED",
  "amount": "150.00"
}

Cancels a pending payment link. Attempts to cancel on the provider side if possible.

POST /api/v1/providers/paylinks/{id}/cancel
Authorization: Bearer <token>

Response

{
  "success": true,
  "paylink_id": "abc123",
  "provider": "tabby",
  "status": "cancelled"
}

Migration from Legacy Endpoints

The provider-specific legacy endpoints (/api/v1/tabby/paylinks, /api/v1/tamara/paylinks, /api/v1/mispay/paylinks) have been permanently removed. All payment link operations must use the unified /api/v1/providers/paylinks endpoints.

Migration Reference

If you were previously using legacy endpoints, update your integration as follows:

Removed EndpointReplacement
POST /api/v1/{provider}/paylinksPOST /api/v1/providers/paylinks with "provider": "{provider}"
GET /api/v1/{provider}/paylinks/{id}GET /api/v1/providers/paylinks/{id}
POST /api/v1/{provider}/paylinks/{id}/capturePOST /api/v1/providers/paylinks/{id}/capture
POST /api/v1/{provider}/paylinks/{id}/cancelPOST /api/v1/providers/paylinks/{id}/cancel
GET /api/v1/providers/{provider}/configGET /api/v1/providers/config/{provider}

POS Integration Flow

The typical POS integration flow using the unified API:

  1. Create — Cashier creates a payment link via POST /api/v1/providers/paylinks with the desired provider
  2. Display — Show the QR code (Tabby/MisPay) or confirm SMS sent (Tamara)
  3. Wait — Customer completes checkout on their device
  4. Webhook — Provider sends status update to the provider-specific webhook endpoint
  5. Capture — Call POST /api/v1/providers/paylinks/{id}/capture to finalize
  6. Done — Order is paid, receipt is printed