Allpay API Reference

API for Israel-based businesses. All requests are POST to https://allpay.to/app/?show=<endpoint>&mode=api12 with a JSON body. The show and mode parameters are passed in the URL query string — not in the JSON body — and are not included in the signature. Authentication uses your API login and a SHA256 signature.

Integration Flows

Choose the flow that matches your use case. Each links to the relevant endpoints.

Most common

Redirect Payment

  1. Call Create Payment → receive payment_url
  2. Redirect the customer to payment_url
  3. Customer enters card details on the Allpay payment page
  4. Allpay POSTs a webhook to your server → verify signature → fulfill order

Best for: standard e-commerce checkout.

Embedded form

Hosted Fields

  1. Call Create Payment with client_name and client_email → receive payment_url
  2. Embed the Hosted Fields iframe on your page using that URL
  3. Customer enters card details directly on your site
  4. Allpay POSTs a webhook → verify signature → fulfill order

Best for: keeping customers on your site. Hosted Fields guide →

Platform-managed billing

Token Billing

  1. Obtain an allpay_token: use Capture Token to save a card without charging, or Get Token from a completed payment
  2. Store the token securely on your side
  3. Whenever you need to charge, call Create Payment with allpay_token
  4. The charge is processed immediately — result returned synchronously; a webhook is sent to webhook_url (if provided)

Best for: SaaS, marketplaces — when you control the billing schedule and amounts.

Allpay-managed billing

Native Allpay Subscription

  1. Call Create Subscription → redirect customer to payment_url
  2. Customer authorizes the first charge
  3. Allpay charges automatically every month and sends a webhook for each charge
  4. Manage via Cancel, Status, and List endpoints

Best for: fixed monthly subscriptions — no billing logic needed on your side.

Two-step payment

Pre-authorization (J5)

  1. Call Create Payment with preauthorize: true → customer authorizes the reservation
  2. Allpay sends a webhook — amount is reserved on the card, not charged
  3. Within 7 days: call Charge Pre-auth to capture (up to reserved amount) — or Refund to void

Best for: deliveries, rentals, variable-weight goods — when the final amount is unknown at authorization time.

Authentication

Every request must include two fields in the JSON body:

FieldTypeDescription
login* string required Your API login — found in Settings → Integrations
sign* string required SHA256 signature of the request body (see algorithm below)

Signature Algorithm

The signature is generated from the request parameters using your private API key.

  1. Remove the sign field from the request.
  2. Exclude all parameters with empty values ("", null, missing).
  3. Sort the remaining keys in alphabetical order (A–Z). Alphabetical sorting must be applied everywhere — to top-level parameters, and to the keys inside each object within array parameters (such as items and subscription).
  4. From the sorted list, take only the parameter values and join them into a single string using a colon : as the separator.
  5. Append your API key to the end of the string, preceded by a colon.
  6. Apply SHA256 to the final string encoded as UTF-8.
Worked Example

Request body (before signing):

{
  "items": [
    {
      "name": "Test payment",
      "price": "1000",
      "qty": "1",
      "discount_val": "0",
      "discount_type": "fixed",
      "vat": "1"
    }
  ],
  "order_id": "1589758an",
  "client_name": "Jason Statham",
  "client_email": "[email protected]",
  "client_tehudat": "000000000",
  "currency": "ILS",
  "currency_display": "ILS",
  "lang": "AUTO",
  "preauthorize": "0",
  "allpay_token": "",       ← excluded (empty string)
  "inst": "",               ← excluded (empty string)
  "doc_type": "",           ← excluded (empty string)
  "button_title": "pay",
  "success_url": "https://example.com/success",
  "webhook_url": "https://example.com/hook/allpay",
  "backlink_url": "",       ← excluded (empty string)
  "login": "pp1008795"
}

Sorted keys A–Z with their values (items[] fields also sorted A–Z and flattened inline):

button_title      → "pay"
client_email      → "[email protected]"
client_name       → "Jason Statham"
client_tehudat    → "000000000"
currency          → "ILS"
currency_display  → "ILS"
items[0]          → discount_type="fixed", discount_val="0", name="Test payment", price="1000", qty="1", vat="1"
lang              → "AUTO"
login             → "pp1008795"
order_id          → "1589758an"
preauthorize      → "0"  ← included ("0" is not empty)
success_url       → "https://example.com/success"
webhook_url       → "https://example.com/hook/allpay"

String to sign (values joined with :, API key appended):

pay:[email protected]:Jason Statham:000000000:ILS:ILS:fixed:0:Test payment:1000:1:1:AUTO:pp1008795:1589758an:0:https://example.com/success:https://example.com/hook/allpay:CB545B50989469F7258C8E043462B30C

SHA256 result:

c3c5458724d88837bd60879b5130c860589e42248360b4ca42c2539ebf8a7803
⚠️ Make sure you follow these steps exactly. 99% of "Invalid signature" errors are caused by: trimming spaces from values, treating 0 as empty (it is a valid value and is included in the signature), or omitting parameters from the signature function. Empty values are "", null, and missing fields only.

Errors

All errors return HTTP 200 with a JSON body containing error_code and error_msg:

{
  "error_code": 3,
  "error_msg":  "Signature is incorrect"
}
error_codeerror_msgDescription
2 Missing required parameters: ... / Wrong param value: ... A required parameter is missing, has an invalid value, or failed validation (price, qty, discount, email format, doc_type eligibility, or a refund amount larger than the part of the order that has not been refunded yet). The error message lists the specific fields.
3 Signature is incorrect The sign parameter does not match the expected SHA256 signature.
5 Login incorrect The login parameter does not match any Allpay account.
6 Order not found / Subscription not found No order or subscription with the given order_id was found for this account.
9 Incorrect token The allpay_token does not exist or is invalid.
12 <processor message> The payment processor declined the token charge. The message contains the processor's reason.
13 Token creation error Failed to retrieve a token for the given order (gettoken endpoint).
15 Order ID ... has already been paid An order with this order_id already exists and has been paid. Use a unique order_id for each payment.
16 Same order can not be charged twice / Refund error: wrong order status Attempted to charge a J5 pre-authorization that was already captured, or to refund an order that is not in a paid state.
17 Processor refund error: ... The payment processor returned an error when processing the refund.
18 Subscription can only include one item The items array contains more than one item in a subscription request.
19 Payment error: wrong order status The payment processor returned an unexpected status when capturing a J5 pre-authorization.
20 Incorrect method The show parameter in the URL contains an unknown or unsupported endpoint name.
21 Amount must be at least 5 ILS The total payment amount (after applying currency rate) is below the minimum of 5 ILS. Applies only to ILS payments (currency = ILS or not specified).
22 Subscriptions module is not enabled for this account A request contained a subscription object, but the Subscriptions module is not active for the account. Enable it in the dashboard (Modules → Subscriptions). Not returned for test payments (test_mode = 1).
const crypto = require('crypto');

function allpaySign(data, apiKey) {
  const d = Object.fromEntries(
    Object.entries({...data})
      .filter(([k, v]) => k !== 'sign' && v !== '' && v != null)
  );
  const chunks = [];
  for (const key of Object.keys(d).sort()) {
    const val = d[key];
    if (Array.isArray(val)) {
      for (const item of val)
        for (const k of Object.keys(item).sort())
          if (item[k] !== '' && item[k] != null)
            chunks.push(String(item[k]));
    } else {
      chunks.push(String(val));
    }
  }
  chunks.push(apiKey);
  return crypto
    .createHash('sha256')
    .update(chunks.join(':'))
    .digest('hex');
}
function allpay_sign(array $data, string $api_key): string {
  unset($data['sign']);
  $data = array_filter($data, fn($v) => $v !== '' && $v !== null);
  ksort($data);
  $chunks = [];
  foreach ($data as $val) {
    if (is_array($val)) {
      foreach ($val as $item) {
        ksort($item);
        foreach ($item as $v)
          if ($v !== '' && $v !== null) $chunks[] = (string)$v;
      }
    } else {
      $chunks[] = (string)$val;
    }
  }
  $chunks[] = $api_key;
  return hash('sha256', implode(':', $chunks));
}
import hashlib

def allpay_sign(data: dict, api_key: str) -> str:
    d = {k: v for k, v in data.items()
         if k != 'sign' and v not in ('', None)}
    chunks = []
    for key in sorted(d):
        val = d[key]
        if isinstance(val, list):
            for item in val:
                for k in sorted(item):
                    if item[k] not in ('', None):
                        chunks.append(str(item[k]))
        else:
            chunks.append(str(val))
    chunks.append(api_key)
    return hashlib.sha256(':'.join(chunks).encode()).hexdigest()

Payments

Create payment links, check status, issue refunds.

Create Payment

POSThttps://allpay.to/app/?show=getpayment&mode=api12

The payment process follows three steps: (1) send a signed POST request to create a payment link, (2) redirect the customer to the returned payment_url, (3) receive a webhook notification at your webhook_url once payment is complete.

Parameters

NameTypeDescription
login*stringrequiredYour API login from Settings → Integrations
order_id*stringrequiredUnique order identifier in your system. Use a unique order_id for each new payment — do not reuse an order_id from a previous paid payment (see error 15).
items*arrayrequiredList of products/services. Displayed in your Allpay account and on accounting documents. The total charge is calculated from item prices × quantities.
FieldTypeRequiredDescription
name* string required Product or service name
qty* number required Quantity
price* number required Unit price. VAT must already be included in the price — it is not added on top.
vat* integer required VAT rate included in the price: 0 — no VAT (VAT-exempt), 1 — 18% VAT, 3 — 0% VAT
discount_val number optional Discount value — deducted from item price
discount_type string optional Whether discount_val is a fixed amount or a percentage: fixed or perc. Required when discount_val is provided.
sign*stringrequiredSHA256 signature
currencystringoptionalThe billing (settlement) currency — the currency in which the customer is charged and your account is settled. If your account does not have permission to process USD or EUR, the amount is automatically converted to ILS using Google Finance exchange rates.
ILSUSDEUR
currency_displaystringoptionalThe display currency shown to the customer on the payment page. The price values in the request must be provided in this currency — Allpay automatically converts the amount to the billing currency. Examples: CAD, AED, RUB. Full list of supported currencies → When currency_display is used, the webhook amount reflects the display currency value (as specified in the request items), while the currency field reflects the billing currency — they refer to different currencies.
langstringoptionalPayment page language.
AUTOENHERUARESITDEFR
button_titlestringoptionalText on the payment button.
paydonatesubscribe
doc_typeintegeroptionalType of the document issued after a successful payment — applies to one-time payments, token payments, and subscription charges. Only takes effect if an accounting service (EasyCount or Morning) is connected to your account — if none is connected, the payment is created normally and simply no document is generated (see the receipt field in the webhook). If not provided, the default document type configured in the accounting service's settings is used.
320 — Tax Invoice Receipt400 — Receipt405 — Receipt for donation
⚠️ If explicitly set to 320 or 405, the request fails if your business type is not eligible to issue that document — this check is unrelated to whether an accounting service is connected.
test_modeintegeroptionalOverrides the integration's test mode setting for this request. If not provided, the default from the integration's settings is used — see Test Cards. For accounts in "developing" status, test mode is forced on and cannot be disabled with this parameter.
0 — live payment1 — test payment, real cards are not charged
webhook_urlstringoptionalAfter a successful or failed payment, Allpay sends a POST webhook with payment details to this URL. If not provided, the transaction will be visible only in your Allpay dashboard.
success_urlstringoptionalThe customer is redirected to this URL after successful payment. If not provided, the customer is redirected to the default Allpay success page.
backlink_urlstringoptionalURL for the "Return to site" button displayed at the bottom of the payment page — allows the customer to return to your checkout. Note: there is no fail URL — payment errors are displayed directly on the payment page, prompting the customer to make a new attempt.
instintegeroptionalMax installment payments offered (1–12)
inst_fixedintegeroptional
0 — customer chooses from 1 up to the inst value1 — number of payments is fixed at the inst value; customer cannot change it
allpay_tokenstringoptionalCharge a card using a saved token — the customer does not need to re-enter card details. The payment is processed immediately and the result is returned synchronously in the API response. A webhook is sent to webhook_url (if provided), same as for regular payments. Use a new, unique order_id for each charge — do not reuse order_ids across recurring charges. On success: {"order_id","status":1}. On failure: {"error_code","error_msg"}.
preauthorizebooleanoptionalIf true, creates a J5 pre-authorization — the amount is reserved on the customer's card for up to 168 hours (7 days), but no charge is made. To collect the funds, a separate Charge Pre-auth request must be sent within this period.
subscriptionobjectoptionalAdd to create a recurring subscription. See Create Subscription.
client_namestringoptionalCustomer's full name (any language). If not provided, the customer will be asked to enter it on the payment page. Required when using Hosted Fields integration.
client_emailstringoptionalCustomer's email address. Used to send an invoice if an accounting service (EasyCount or Morning) is connected. If not provided, the customer will be asked to enter it on the payment page. Required when using Hosted Fields integration.
client_phonestringoptionalCustomer's phone number.
client_tehudatstringoptionalFor private customers — Social ID (Tehudat Zehut); for companies — Company Number (Mispar Het Pey). Pass "000000000" to hide this field and skip the ID request for non-Israeli customers.
show_applepaybooleanoptionalShow Apple Pay button (module must be active)
show_bitbooleanoptionalShow Bit payment button (module must be active)
add_field_1stringoptionalAny additional data about the order or customer — returned unchanged in the webhook.
add_field_2stringoptionalAny additional data about the order or customer — returned unchanged in the webhook.
expireintegeroptionalUnix timestamp when the payment link expires (default: 1 week)

Response

Redirect flow (no allpay_token):

FieldTypeDescription
payment_urlstringURL to redirect the customer to

Token payment flow (allpay_token provided) — on success:

FieldTypeDescription
order_idstringOrder identifier
statusinteger1 — charge successful

A webhook is sent to webhook_url (if provided) — identical in structure to webhooks from regular (redirect-flow) payments.

On failure:

FieldTypeDescription
error_codeintegerError code from the payment processor
error_msgstringHuman-readable error description
// Redirect flow
{ "payment_url": "https://allpay.to/~login/pay/?payment_id=abc123&code=xyz" }

// Token flow — success
{ "order_id": "ORDER-001", "status": 1 }

// Token flow — failure
{ "error_code": 12, "error_msg": "Payment declined" }
curl https://allpay.to/app/?show=getpayment&mode=api12 \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "ORDER-001",
    "items": [{
      "name": "Product A",
      "qty": 1,
      "price": 100,
      "vat": 1
    }],
    "currency": "ILS",
    "webhook_url": "https://yoursite.com/webhook",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
const crypto = require('crypto');

function allpaySign(data, apiKey) {
  const d = Object.fromEntries(
    Object.entries({...data})
      .filter(([k, v]) => k !== 'sign' && v !== '' && v != null)
  );
  const chunks = [];
  for (const key of Object.keys(d).sort()) {
    const val = d[key];
    if (Array.isArray(val)) {
      for (const item of val)
        for (const k of Object.keys(item).sort())
          if (item[k] !== '' && item[k] != null) chunks.push(String(item[k]));
    } else chunks.push(String(val));
  }
  chunks.push(apiKey);
  return crypto.createHash('sha256').update(chunks.join(':')).digest('hex');
}

const body = {
  login: 'your_login',
  order_id: 'ORDER-001',
  items: [{ name: 'Product A', qty: '1', price: '100', vat: '1' }],
  currency: 'ILS',
  webhook_url: 'https://yoursite.com/webhook'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');

const res = await fetch('https://allpay.to/app/?show=getpayment&mode=api12', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
});
const { payment_url } = await res.json();
function allpay_sign(array $data, string $api_key): string {
  unset($data['sign']);
  $data = array_filter($data, fn($v) => $v !== '' && $v !== null);
  ksort($data);
  $chunks = [];
  foreach ($data as $val) {
    if (is_array($val)) {
      foreach ($val as $item) {
        ksort($item);
        foreach ($item as $v)
          if ($v !== '' && $v !== null) $chunks[] = (string)$v;
      }
    } else { $chunks[] = (string)$val; }
  }
  $chunks[] = $api_key;
  return hash('sha256', implode(':', $chunks));
}

$body = [
  'login'    => 'your_login',
  'order_id' => 'ORDER-001',
  'items'    => [[
    'name' => 'Product A', 'qty' => '1',
    'price' => '100',       'vat' => '1'
  ]],
  'currency'    => 'ILS',
  'webhook_url' => 'https://yoursite.com/webhook'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');

$ch = curl_init('https://allpay.to/app/?show=getpayment&mode=api12');
curl_setopt_array($ch, [
  CURLOPT_POST           => true,
  CURLOPT_POSTFIELDS     => json_encode($body),
  CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
  CURLOPT_RETURNTRANSFER => true
]);
$response = json_decode(curl_exec($ch), true);
$payment_url = $response['payment_url'];
import hashlib, requests

def allpay_sign(data: dict, api_key: str) -> str:
    d = {k: v for k, v in data.items()
         if k != 'sign' and v not in ('', None)}
    chunks = []
    for key in sorted(d):
        val = d[key]
        if isinstance(val, list):
            for item in val:
                for k in sorted(item):
                    if item[k] not in ('', None):
                        chunks.append(str(item[k]))
        else: chunks.append(str(val))
    chunks.append(api_key)
    return hashlib.sha256(':'.join(chunks).encode()).hexdigest()

body = {
    'login': 'your_login',
    'order_id': 'ORDER-001',
    'items': [{'name': 'Product A', 'qty': '1',
               'price': '100', 'vat': '1'}],
    'currency': 'ILS',
    'webhook_url': 'https://yoursite.com/webhook'
}
body['sign'] = allpay_sign(body, 'YOUR_API_KEY')
res = requests.post('https://allpay.to/app/?show=getpayment&mode=api12', json=body)
payment_url = res.json()['payment_url']
# cURL
curl https://allpay.to/app/?show=getpayment&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "ORDER-002",
    "items": [{"name": "Monthly CRM plan", "qty": "1", "price": "49.00", "vat": "1"}],
    "currency": "ILS",
    "allpay_token": "TOKEN_VALUE",
    "sign": "YOUR_COMPUTED_SIGN"
  }'

// Node.js
const body = {
  login: 'your_login',
  order_id: 'ORDER-002',
  items: [{ name: 'Monthly CRM plan', qty: '1', price: '49.00', vat: '1' }],
  currency: 'ILS',
  allpay_token: 'TOKEN_VALUE'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const res = await (await fetch('https://allpay.to/app/?show=getpayment&mode=api12', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
})).json();
// success: { order_id, status: 1 }
// failure: { error_code, error_msg }

// PHP
$body = [
  'login'        => 'your_login',
  'order_id'     => 'ORDER-002',
  'items'        => [['name' => 'Monthly CRM plan', 'qty' => '1', 'price' => '49.00', 'vat' => '1']],
  'currency'     => 'ILS',
  'allpay_token' => 'TOKEN_VALUE'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=getpayment&mode=api12
// success: ['order_id' => ..., 'status' => 1]
// failure: ['error_code' => 12, 'error_msg' => '...']

Payment Webhook

Allpay sends a POST request with Content-Type: application/json and a JSON body to your webhook_url after every payment attempt — both successful and failed. Respond with HTTP 200 to acknowledge. Allpay makes up to 10 delivery attempts total — the first retry 1 minute after the initial failure, then with progressively increasing intervals, with the final attempt within 24 hours.

✅ Always verify the signature before processing. A payment is confirmed only when status == 1.

Payload Fields

FieldTypeDescription
order_idstringYour order identifier
statusinteger
0 — unpaid / failed1 — successful
amountnumberPayment amount.
subscription_createintegerPresent only in webhooks where no money was charged: subscription creation with a deferred start, and Capture Token. Absent from every webhook that reports an actual charge.
0 — card saved, no subscription created1 — subscription created, first charge scheduled
currencystringILS / USD / EUR
instintegerNumber of installment payments
card_maskstringMasked card number, e.g. 465901******7049
card_brandstringVisa / Mastercard / AmEx / Diners
foreign_cardinteger
0 — local card (issued by an Israeli bank)1 — foreign card
receiptstringURL to the digital receipt. Generated only if an accounting service (EasyCount or Morning) is connected in your Allpay account.
client_namestringCustomer name
client_emailstringCustomer email
client_phonestringCustomer phone
client_tehudatstringCustomer Social ID (if provided)
add_field_1stringCustom data from request (unchanged)
add_field_2stringCustom data from request (unchanged)
signstringSHA256 signature — verify using your API key
Important: status = 0 in a webhook means that this payment attempt failed. It does not mean the order is permanently cancelled — the customer may still retry payment on the same payment page. Fulfill the order only when status = 1 and the signature is valid.
{
  "order_id":      "ORDER-001",
  "status":       1,
  "amount":       100.00,
  "currency":     "ILS",
  "inst":         1,
  "card_mask":    "465901******7049",
  "card_brand":   "Visa",
  "foreign_card": 0,
  "client_name":  "Joe Doe",
  "client_email": "[email protected]",
  "add_field_1":  "your-data",
  "sign":         "abc123..."
}
$payload = json_decode(file_get_contents('php://input'), true);
$received_sign = $payload['sign'] ?? '';

// Verify signature first
$expected = allpay_sign($payload, 'YOUR_API_KEY');
if (!hash_equals($expected, $received_sign)) {
  http_response_code(400);
  exit;
}

// Fulfill order only on successful payment
if ((int)$payload['status'] === 1) {
  fulfill_order($payload['order_id'], $payload['amount']);
}

// Always acknowledge receipt — including failed payment attempts
http_response_code(200);
echo 'OK';
app.post('/webhook', (req, res) => {
  const payload = req.body;
  const expected = allpaySign(payload, 'YOUR_API_KEY');

  // Use timing-safe comparison
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(payload.sign))) {
    return res.sendStatus(400);
  }

  if (payload.status === 1) {
    fulfillOrder(payload.order_id, payload.amount);
  }

  // Always respond 200 — including failed payment attempts
  res.sendStatus(200);
});

Chargeback Webhook

Allpay sends a separate POST request to the same webhook_url when the card issuer charges an order back, and again if that chargeback is later reverted. Delivery, retries and signature work exactly as for the Payment Webhook.

⚠️ Distinguish this webhook by the type field.

Payload Fields

FieldTypeDescription
typestring
chargeback — the issuer withdrew the money from youchargeback_revert — a previous chargeback was cancelled and the money returned to you
statusintegerState of the original order, the same value Check Payment Status would return at that moment.
1 — nothing withdrawn from the order3 — the whole order has been charged back or refunded4 — partially charged back or refunded
amountnumberAmount of this operation — how much was withdrawn (chargeback) or returned (chargeback_revert). Always positive.
refundednumberTotal already charged back or refunded on this order, including the current operation.
order_amountnumberFull charged amount of the original order (order sum minus any discount).
currencystringILS / USD / EUR — the currency all amounts in this payload are expressed in
order_idstringYour order identifier. Present when the original payment was created via the API.
namestringName of the original order
itemsarrayPositions of the original order.
receiptstringURL to the document issued for this operation (negative receipt for a chargeback).
receipt_taxstringLink to the credit tax invoice.
card_maskstringMasked card number of the original payment
card_brandstringVisa / Mastercard / AmEx / Diners
foreign_cardinteger
0 — local card (issued by an Israeli bank)1 — foreign card
client_namestringCustomer name
client_emailstringCustomer email
client_phonestringCustomer phone
client_tehudatstringCustomer Social ID (if provided)
add_field_1stringCustom data from the original request (unchanged)
add_field_2stringCustom data from the original request (unchanged)
signstringSHA256 signature — verify using your API key
// Full chargeback of a 100.00 ILS order
{
  "type":         "chargeback",
  "status":       3,
  "amount":       100.00,
  "refunded":     100.00,
  "order_amount": 100.00,
  "currency":     "ILS",
  "order_id":     "ORDER-001",
  "card_mask":    "465901******7049",
  "card_brand":   "Visa",
  "foreign_card": 0,
  "client_name":  "Joe Doe",
  "sign":         "abc123..."
}

// The same chargeback later reverted — status stays 3
{
  "type":         "chargeback_revert",
  "status":       3,
  "amount":       100.00,
  "refunded":     100.00,
  "order_amount": 100.00,
  "currency":     "ILS",
  "order_id":     "ORDER-001",
  "sign":         "abc123..."
}
$payload = json_decode(file_get_contents('php://input'), true);

// Verify the signature exactly as for a payment webhook
$expected = allpay_sign($payload, 'YOUR_API_KEY');
if (!hash_equals($expected, $payload['sign'] ?? '')) {
  http_response_code(400);
  exit;
}

switch ($payload['type'] ?? '') {

  case 'chargeback':
    // Money withdrawn: block the order, open a dispute
    on_chargeback($payload['order_id'], $payload['amount']);
    break;

  case 'chargeback_revert':
    // Dispute won: money is back
    on_chargeback_revert($payload['order_id'], $payload['amount']);
    break;

  default:
    // No "type" — this is a regular payment webhook
    if ((int)$payload['status'] === 1) {
      fulfill_order($payload['order_id'], $payload['amount']);
    }
}

http_response_code(200);
echo 'OK';

Check Payment Status

POSThttps://allpay.to/app/?show=paymentstatus&mode=api12

Check the status of a payment. Call at least 2 seconds after the payment attempt.

Parameters

NameTypeDescription
login*stringrequiredAPI login
order_id*stringrequiredOrder identifier
sign*stringrequiredSHA256 signature

Response

FieldTypeDescription
order_idstringOrder identifier
statusinteger
0 — unpaid / not yet completed (payment attempt may have failed; customer can still retry)1 — successful3 — refunded4 — partially refunded (the response also contains the refunded field)
amountnumberPayment amount
refundednumberRefunded part of the payment, in the same currency as amount. Returned only when status is 4 (partial refund) — the field is absent for all other statuses. Once the whole charged sum (amount minus any discount applied to the order) has been refunded, the status becomes 3 and the field is no longer returned.
currencystringBilling currency
instintegerInstallment count
card_maskstringMasked card number
card_brandstringCard brand
foreign_cardinteger
0 — local card (issued by an Israeli bank)1 — foreign card
receiptstringURL to the digital receipt. Generated only if an accounting service (EasyCount or Morning) is connected in your Allpay account.
client_name / email / phone / tehudatstringCustomer details
{
  "order_id":      "ORDER-001",
  "status":       1,
  "amount":       100.00,
  "inst":         1,
  "currency":     "ILS",
  "foreign_card": 0,
  "card_mask":    "465901******7049",
  "card_brand":   "Visa",
  "receipt":      "",
  "client_name":  "Joe Doe",
  "client_email": "[email protected]",
  "client_phone": "+972501234567",
  "client_tehudat": "123456789"
}

// Partially refunded payment (status 4) — "refunded" is added
{
  "order_id":      "ORDER-001",
  "status":       4,
  "amount":       100.00,
  "refunded":     30.00,
  "inst":         1,
  "currency":     "ILS",
  "foreign_card": 0,
  "card_mask":    "465901******7049",
  "card_brand":   "Visa",
  "receipt":      "",
  "client_name":  "Joe Doe",
  "client_email": "[email protected]",
  "client_phone": "+972501234567",
  "client_tehudat": "123456789"
}
curl https://allpay.to/app/?show=paymentstatus&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "ORDER-001",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'    => 'your_login',
  'order_id' => 'ORDER-001'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=paymentstatus&mode=api12
// $response['status']: 0=unpaid, 1=paid, 3=refunded, 4=partial refund
// on status 4 the response also contains $response['refunded'] — the refunded part
const body = {
  login: 'your_login', order_id: 'ORDER-001'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { status, amount, refunded, currency } = await (await fetch('https://allpay.to/app/?show=paymentstatus&mode=api12', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
})).json();
// status: 0=unpaid, 1=paid, 3=refunded, 4=partial refund
// refunded is present only when status === 4

Refund Payment

POSThttps://allpay.to/app/?show=refund&mode=api12

Issue a full or partial refund. The refunded sum is taken from amount, or from items when you refund specific positions. Refunds are processed from your available withdrawal balance.

Parameters

NameTypeDescription
login*stringrequiredAPI login
order_id*stringrequiredOrder identifier
amount*stringrequiredRefund amount as a string (e.g. "100.00") — the sum actually returned to the customer, in the currency the payment was charged in. Pass the full order amount for a full refund, or a smaller value for a partial one. Must not exceed the part of the order that has not been refunded yet.
sign*stringrequiredSHA256 signature
itemsarrayoptionalFor a refund by item: array matching the original items count and order. Each object has one field: amount (string). Use "0" to skip an item. Takes precedence over amount — when this array is present, the refund total is the sum of its values, subject to the same limit.

Response

FieldTypeDescription
order_idstringOrder identifier
msgstringHuman-readable result message, e.g. The amount will be refunded to the customer's card within 7 business days.
statusinteger
3 — fully refunded4 — partially refunded
receiptstringLink to the refund receipt (negative receipt). Present only when refund documents were created — i.e. the original payment has a receipt issued via a connected accounting service (EasyCount or Morning).
receipt_taxstringLink to the credit tax invoice. Present only for VAT-registered businesses, which receive two refund documents: a credit tax invoice and a negative receipt.
{
  "order_id":    "ORDER-001",
  "msg":         "The amount will be refunded to the customer's card within 7 business days.",
  "status":      3,
  "receipt":     "https://...",
  "receipt_tax": "https://..."
}

// receipt / receipt_tax are included only when refund documents
// were created (an accounting service — EasyCount or Morning — is connected).
// receipt_tax is issued only for VAT-registered businesses.
# Full refund — amount equals the order total
curl https://allpay.to/app/?show=refund&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "ORDER-001",
    "amount": "100.00",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
// Partial refund: return 200.00 of a larger order
$body = [
  'login'    => 'your_login',
  'order_id' => 'ORDER-001',
  'amount'   => '200.00'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=refund&mode=api12
// The order status becomes 4 (partially refunded) while a refundable part remains.
// Full refund — amount equals the order total
const body = {
  login: 'your_login', order_id: 'ORDER-001',
  amount: '100.00'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { status } = await (await fetch('https://allpay.to/app/?show=refund&mode=api12', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
})).json();
// status 3 = fully refunded, 4 = partially refunded

Subscriptions

Create and manage recurring billing. Currently, only monthly frequency is supported. Requires the Subscriptions module to be active on your account.

Create Subscription

POSThttps://allpay.to/app/?show=getpayment&mode=api12

Same as Create Payment but with an additional subscription object. Returns a payment_url for the customer to authorize the first charge. Subsequent charges happen automatically each month with webhooks sent for each. If the subscription object is omitted, the request is processed as a regular one-time payment.

⚠️ With start_type=2 or start_type=3, the first charge is deferred, so the card is not sent to the issuing bank for authorization when the customer submits the payment page. This means an incorrect card number will pass this step and the subscription will be created successfully — the error will only surface later, when the first scheduled charge is attempted. To confirm the card is valid up front, use start_type=1 so the first charge happens immediately on the payment page.

subscription object

NameTypeDescription
start_type*integerrequiredWhen first charge occurs:
1 — immediately (the customer is charged when they complete the payment page)2 — specific date (start_date)3 — after N days (start_n)
start_dateintegeroptionalUnix timestamp (required if start_type=2). Only the date part is used — see note below.
start_nintegeroptionalNumber of days (required if start_type=3)
end_type*integerrequiredWhen subscription ends:
1 — infinite2 — specific date (end_date)3 — after N charges (end_n)
end_dateintegeroptionalUnix timestamp (required if end_type=2). Only the date part is used — see note below.
end_nintegeroptionalNumber of charges (required if end_type=3). Minimum 1: with end_n=1 and start_type=1 the customer is charged once on the payment page and the subscription completes immediately; with a deferred start the single charge occurs on the scheduled date.
⚠️ start_date / end_date select a calendar day, not an exact moment. Charges are not triggered at the exact second the timestamp represents. Instead, a daily batch job (running once a day, Israel time) charges every subscription whose scheduled date has arrived or already passed. The time-of-day portion of the timestamp is stored and shown in the dashboard/API responses, but it has no effect on when the charge actually runs. A practical consequence: if start_date is set to a time on the same calendar day the subscription is created, and that day's batch has already run, the first charge is postponed to the next day's batch — it is not executed later that same day. To guarantee same-day behavior, use start_type=1 (immediate); for a scheduled first charge, set start_date to the next calendar day or later.
Note: The Subscriptions module must be enabled for your account before subscriptions can be created via the API. If it is not, the request fails with error 22Subscriptions module is not enabled for this account. Test payments (test_mode = 1) are not affected.
Note: Subscriptions can include only one item in the items array (see error 18). If you need to describe multiple components, combine them into one item name or manage billing on your side using tokens.

Additional top-level parameter

NameTypeDescription
button_titlestringoptionalButton text. Default for subscriptions is subscribe.
subscribepaydonate
Subscription charge webhooks use the same structure as Payment Webhook. The order_id in every webhook — including the first charge and all recurring charges — is the original subscription order_id. Each successful charge has status = 1; a failed charge has status = 0. There is no field in the webhook payload that identifies the specific recurring charge or distinguishes it from the first charge.
Deferred start — the subscription-creation webhook is not a charge. With any deferred start_type — that is, anything other than 1 — no money is taken when the customer submits their card. Allpay saves the card, creates the subscription, and immediately sends a webhook with status = 1 — which here means the card was saved successfully, not that a payment was made. That webhook carries amount = 0, while the items array still holds the subscription price. Do not fulfill the order on it. Wait for the first charge webhook, which arrives after the scheduled charge, carries the amount actually charged.
curl https://allpay.to/app/?show=getpayment&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "SUB-001",
    "items": [{"name": "Monthly Plan", "qty": "1", "price": "49", "vat": "1"}],
    "currency": "ILS",
    "webhook_url": "https://yoursite.com/webhook",
    "button_title": "subscribe",
    "subscription": {"start_type": 1, "end_type": 1},
    "sign": "YOUR_COMPUTED_SIGN"
  }'
const body = {
  login: 'your_login',
  order_id: 'SUB-001',
  items: [{ name: 'Monthly Plan', qty: '1', price: '49', vat: '1' }],
  currency: 'ILS',
  webhook_url: 'https://yoursite.com/webhook',
  button_title: 'subscribe',
  subscription: {
    start_type: 1,   // immediately
    end_type:   1    // infinite
  }
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
$body = [
  'login'    => 'your_login',
  'order_id' => 'SUB-001',
  'items'    => [['name' => 'Monthly Plan', 'qty' => '1', 'price' => '49', 'vat' => '1']],
  'currency'  => 'ILS',
  'webhook_url' => 'https://yoursite.com/webhook',
  'subscription' => [
    'start_type' => 3, 'start_n' => 7,  // first charge after 7 days
    'end_type'   => 3, 'end_n'   => 12  // cancel after 12 charges
  ]
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=getpayment&mode=api12
body = {
    'login': 'your_login',
    'order_id': 'SUB-001',
    'items': [{'name': 'Monthly Plan', 'qty': '1',
               'price': '49', 'vat': '1'}],
    'currency': 'ILS',
    'subscription': {
        'start_type': '1', 'end_type': '1'
    }
}
body['sign'] = allpay_sign(body, 'YOUR_API_KEY')
# POST to https://allpay.to/app/?show=getpayment&mode=api12

Cancel Subscription

POSThttps://allpay.to/app/?show=cancelsubscription&mode=api12

Parameters

NameTypeDescription
login*stringrequiredAPI login
order_id*stringrequiredSubscription order ID
sign*stringrequiredSHA256 signature

Response

FieldTypeDescription
statusintegerAfter cancellation you can expect 4 or 2 (subscription was already completed — no cancellation needed).
1 — active2 — completed3 — error4 — cancelled
curl https://allpay.to/app/?show=cancelsubscription&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "SUB-001",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'    => 'your_login',
  'order_id' => 'SUB-001'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=cancelsubscription&mode=api12
// status 4 = cancelled, 2 = already completed
const body = {
  login: 'your_login', order_id: 'SUB-001'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { status } = await (await fetch('https://allpay.to/app/?show=cancelsubscription&mode=api12', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
})).json();
// status 4 = cancelled, 2 = already completed

Subscription Status

POSThttps://allpay.to/app/?show=subscriptionstatus&mode=api12

Get detailed status and full charge history of a subscription.

Parameters

NameTypeDescription
login*stringrequiredAPI login
order_id*stringrequiredSubscription order ID
sign*stringrequiredSHA256 signature

Response

FieldTypeDescription
order_idstringSubscription ID
statusinteger
1 — active2 — completed3 — error (last charge failed, retry tomorrow)4 — cancelled
amountnumberAmount per charge
currencystringILS / USD / EUR
payments_nintegerNumber of successful charges
paid_totalnumberTotal amount charged
paymentsarrayCharge history: each item has ts (Unix timestamp), amount, receipt (URL)
{
  "order_id":    "SUB-001",
  "status":     1,
  "amount":     49.00,
  "currency":   "ILS",
  "payments_n": 3,
  "paid_total": 147.00,
  "payments": [
    { "ts": 1748131200, "amount": 49.00, "receipt": "" },
    { "ts": 1745539200, "amount": 49.00, "receipt": "" },
    { "ts": 1742947200, "amount": 49.00, "receipt": "" }
  ]
}
curl https://allpay.to/app/?show=subscriptionstatus&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "SUB-001",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'    => 'your_login',
  'order_id' => 'SUB-001'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=subscriptionstatus&mode=api12
// $response['status']: 1=active, 2=completed, 3=error, 4=cancelled
// $response['payments_n'] — successful charges count
// $response['paid_total'] — total charged amount
const body = {
  login: 'your_login', order_id: 'SUB-001'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { status, payments_n, paid_total } =
  await (await fetch('https://allpay.to/app/?show=subscriptionstatus&mode=api12',
    { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(body) }
  )).json();
// status: 1=active, 2=completed, 3=error, 4=cancelled

List Subscriptions

POSThttps://allpay.to/app/?show=getsubscriptions&mode=api12

Returns a paginated list of subscriptions created via API under this API login (100 per page). Subscriptions created from the dashboard or under a different API login are not included.

Parameters

NameTypeDescription
login*stringrequiredAPI login
sign*stringrequiredSHA256 signature
statusintegeroptionalFilter by subscription status. If omitted or set to 0, returns all subscriptions regardless of status.
0 — any1 — active2 — completed3 — error4 — cancelled
pageintegeroptionalPage number to retrieve. If not provided, the first page is returned. Each page contains up to 100 subscriptions.

Response

FieldTypeDescription
total_nintegerTotal subscriptions returned
next_pageintegerNext page number, or 0 if no more pages
subscriptionsarrayArray of subscription objects.
FieldTypeDescription
order_idstringSubscription order identifier
namestringSubscription name (from the first item)
statusinteger
1 — active2 — completed3 — error4 — cancelled
amountnumberAmount per charge
currencystringILS / USD / EUR
payments_nintegerNumber of successful charges made
paid_totalnumberTotal amount charged to date
date_startintegerUnix timestamp of the first charge
date_endintegerUnix timestamp of the last charge; 0 for infinite subscriptions
next_paymentintegerUnix timestamp of the next scheduled charge
client_namestringCustomer name
client_emailstringCustomer email
client_phonestringCustomer phone
client_tehudatstringCustomer Social ID (if provided)
add_field_1stringCustom data from the original request (if provided)
add_field_2stringCustom data from the original request (if provided)
{
  "total_n":  1,
  "next_page": 0,
  "subscriptions": [{
    "order_id":      "SUB-001",
    "name":         "Monthly Plan",
    "status":       1,
    "amount":       49.00,
    "currency":     "ILS",
    "payments_n":   3,
    "paid_total":   147.00,
    "date_start":   1742947200,
    "date_end":     0,  // 0 = infinite
    "next_payment": 1750723200,
    "client_name":  "Joe Doe",
    "client_email": "[email protected]",
    "client_phone": "+972501234567",
    "client_tehudat": "123456789",
    "add_field_1":  "custom-data",
    "add_field_2":  ""
  }]
}
curl https://allpay.to/app/?show=getsubscriptions&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "status": "1",
    "page": "1",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'  => 'your_login',
  'status' => '1', // active only
  'page'   => '1'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=getsubscriptions&mode=api12
// $response['subscriptions'] — array of subscriptions
// $response['next_page'] — 0 if no more pages
const body = {
  login: 'your_login', status: '1', page: '1'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { subscriptions, total_n, next_page } = await (await fetch('https://allpay.to/app/?show=getsubscriptions&mode=api12', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
})).json();

Subscription Statistics

POSThttps://allpay.to/app/?show=subscriptionsinfo&mode=api12

Statistical breakdown of subscriptions grouped by status.

Parameters

NameTypeDescription
login*stringrequiredAPI login
sign*stringrequiredSHA256 signature

Response

info — array, one entry per status group:

FieldTypeDescription
statusinteger
1 — active2 — completed3 — error4 — cancelled
total_nintegerNumber of subscriptions with this status
total_amountnumberSum of all subscription amounts for this status group
{
  "info": [
    { "status": 1, "total_n": 42, "total_amount": 2058.00 },
    { "status": 2, "total_n":  5, "total_amount":  245.00 },
    { "status": 4, "total_n":  7, "total_amount":  343.00 }
  ]
}
curl https://allpay.to/app/?show=subscriptionsinfo&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login' => 'your_login'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=subscriptionsinfo&mode=api12
// $response['info'][0] = ['status' => 1, 'total_n' => 42, 'total_amount' => 2058.00]
const body = { login: 'your_login' };
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { info } = await (await fetch('https://allpay.to/app/?show=subscriptionsinfo&mode=api12', {
  method: 'POST', headers: {'Content-Type': 'application/json'},
  body: JSON.stringify(body)
})).json();
// info[0] = { status: 1, total_n: 42, total_amount: 2058.00 }

Tokens

Save a card without charging, then reuse it for future payments without requiring the customer to re-enter card details.

We recommend using the token API endpoints when building billing for SaaS products. For SaaS services, Allpay's token API endpoints provide more flexible billing management than the Subscriptions API. Once a card token has been obtained, your system can submit it via the API for each new payment while independently determining the amount, date, and conditions of the charge. This allows you to change pricing plans and implement custom recurring payment scenarios that match your product's business model.

⚠️ Bit and Apple Pay do not support tokenization.
🔒 Before charging a customer's card using a token, ensure you have their explicit consent. Unauthorized charges may result in withdrawal of your acquiring permission and blocking of your Allpay account. Recommendations for designing a billing interface →

Capture Token Without Payment

POSThttps://allpay.to/app/?show=capturetoken&mode=api12

Creates a card capture session. Returns a payment_url where the customer enters their card details — no charge is made. In case of a successful card capture, Allpay sends a POST webhook to your webhook_url. The webhook includes the allpay_token, which can be used to initiate a new payment or a subscription.

⚠️ Since no charge is made, the card is never sent to the issuing bank for authorization, so this endpoint cannot verify that the card is valid. A token will be created even for an incorrect card number, and the error will only surface later, when the first real charge against that token is attempted. To confirm a card is valid before saving it for future use, charge it via Create Payment and then retrieve the token for that payment with Get Token.

Parameters

NameTypeDescription
login*stringrequiredAPI login
order_id*stringrequiredUnique identifier in your system. Use a unique order_id for each capture session — do not reuse an order_id from a previous capture.
items*arrayrequiredItems for display only (no charge). Only name field is required per item.
sign*stringrequiredSHA256 signature
button_titlestringoptionalSubmit button text.
submitsavesubscribepaydonate
langstringoptionalPage language (AUTO, EN, HE, RU, AR, ES, IT, DE, FR)
webhook_urlstringoptionalAllpay sends a POST webhook with card details, capture status, and allpay_token to this URL.
success_urlstringoptionalThe customer is redirected to this URL after the token is captured. If not provided, the customer is redirected to the default Allpay success page.
backlink_urlstringoptionalURL for the "Return to site" button displayed at the bottom of the page. Note: there is no fail URL — errors are displayed directly on the page, prompting the customer to try again.
client_name / email / phone / tehudatstringoptionalPrefill customer fields
add_field_1 / add_field_2stringoptionalCustom data — returned in webhook
expireintegeroptionalUnix timestamp when link expires (default: 1 week)

API Response

payment_urlstringRedirect the customer here

Webhook (after customer submits card)

Success (status = 1):

FieldTypeDescription
order_idstringYour order identifier
statusinteger1 — token captured successfully
amountnumberAlways 0 — capturing a token does not charge the card
subscription_createintegerAlways 0 — a card was saved without creating a subscription
allpay_tokenstringToken representing the customer's card — use in future Create Payment calls or Create Subscription
itemsarrayItems from the request
card_maskstringMasked card number, e.g. 465901******7049
card_brandstringVisa / Mastercard / AmEx / Diners
foreign_cardinteger
0 — local card (issued by an Israeli bank)1 — foreign card
client_namestringCustomer name (if provided in request)
client_emailstringCustomer email (if provided in request)
client_phonestringCustomer phone (if provided in request)
client_tehudatstringCustomer Social ID (if provided in request)
signstringSHA256 signature — verify using your API key

Failed (status = 0):

FieldTypeDescription
order_idstringYour order identifier
statusinteger0 — capture failed
errorstringError description from the processor
signstringSHA256 signature — verify using your API key
// success (status = 1)
{
  "order_id":      "TOKEN-001",
  "status":        1,
  "allpay_token":  "6A0874314DCA42-79412113",
  "items":         [{ "name": "Save payment method" }],
  "card_mask":     "465901******7049",
  "card_brand":   "Visa",
  "foreign_card": 0,
  "client_name":  "Joe Doe",
  "client_email": "[email protected]",
  "sign":         "abc123..."
}

// failed (status = 0)
{
  "order_id": "TOKEN-001",
  "status":   0,
  "error":    "Card declined",
  "sign":     "abc123..."
}
curl https://allpay.to/app/?show=capturetoken&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "TOKEN-001",
    "items": [{"name": "Save payment method"}],
    "button_title": "save",
    "webhook_url": "https://yoursite.com/token-webhook",
    "lang": "EN",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'       => 'your_login',
  'order_id'    => 'TOKEN-001',
  'items'       => [['name' => 'Save payment method']],
  'button_title' => 'save',
  'webhook_url' => 'https://yoursite.com/token-webhook'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=capturetoken&mode=api12
// redirect to $response['payment_url']
// webhook: { status:1, order_id:'TOKEN-001', allpay_token:'6A0874314DCA42-...', card_mask:'465901******7049', card_brand:'Visa', ... }
const body = {
  login: 'your_login',
  order_id: 'TOKEN-001',
  items: [{ name: 'Save payment method' }],
  button_title: 'save',
  webhook_url: 'https://yoursite.com/token-webhook',
  lang: 'EN'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { payment_url } = await (await fetch('https://allpay.to/app/?show=capturetoken&mode=api12', {
  method: 'POST', headers: {'Content-Type': 'application/json'},
  body: JSON.stringify(body)
})).json();
// redirect customer to payment_url
// webhook: { status: 1, order_id: 'TOKEN-001', allpay_token: '6A0874314DCA42-...', card_mask: '465901******7049', card_brand: 'Visa', ... }

Get Token for Existing Payment

POSThttps://allpay.to/app/?show=gettoken&mode=api12

Retrieve a reusable token from a completed payment.

ℹ️ Bit payments do not support tokenization.

Parameters

NameTypeDescription
login*stringrequiredAPI login
order_id*stringrequiredOrder ID of the completed payment
sign*stringrequiredSHA256 signature

Response

FieldTypeDescription
order_idstringOrder identifier
allpay_tokenstringToken for future payments
card_maskstringMasked card number
card_brandstringCard brand
foreign_cardinteger
0 — local card (issued by an Israeli bank)1 — foreign card
curl https://allpay.to/app/?show=gettoken&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "ORDER-001",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'    => 'your_login',
  'order_id' => 'ORDER-001'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=gettoken&mode=api12
// $response['allpay_token'] — use in future getpayment calls
const body = {
  login: 'your_login', order_id: 'ORDER-001'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { allpay_token, card_mask } = await (await fetch('https://allpay.to/app/?show=gettoken&mode=api12', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
})).json();
// pass allpay_token in future Create Payment calls

J5 / Pre-authorization

Reserve an amount on a card without charging it. The reservation is valid for 7 days (168 hours). You can charge an amount equal to or less than the reserved amount — but only once. To void a reservation without charging, call the Refund endpoint.

Pre-authorize (Reserve)

POSThttps://allpay.to/app/?show=getpayment&mode=api12

Same as Create Payment with preauthorize: true. Reserves the amount on the customer's card — no charge is made. Returns payment_url.

⚠️ The reservation expires after 168 hours (7 days). Charge or void it before then.
preauthorizebooleanSet to true
curl https://allpay.to/app/?show=getpayment&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "J5-001",
    "items": [{"name": "Hotel reservation", "qty": "1", "price": "500", "vat": "1"}],
    "preauthorize": true,
    "webhook_url": "https://yoursite.com/webhook",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'        => 'your_login',
  'order_id'     => 'J5-001',
  'items'        => [['name' => 'Hotel reservation', 'qty' => '1', 'price' => '500', 'vat' => '1']],
  'preauthorize' => true,
  'webhook_url'  => 'https://yoursite.com/webhook'
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=getpayment&mode=api12
// redirect to $response['payment_url']
const body = {
  login: 'your_login', order_id: 'J5-001',
  items: [{ name: 'Hotel reservation', qty: '1', price: '500', vat: '1' }],
  preauthorize: true,
  webhook_url: 'https://yoursite.com/webhook'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');

Charge Pre-authorized Payment

POSThttps://allpay.to/app/?show=runauthorizedpayment&mode=api12

Charge a reserved amount. Can only be done once, must not exceed the reserved amount, and must happen within 168 hours.

ℹ️ To void a reservation without charging, call Refund without an items field.

Parameters

NameTypeDescription
login*stringrequiredAPI login
order_id*stringrequiredOrder ID from the original pre-authorization
amount*numberrequiredAmount to charge (≤ reserved amount)
sign*stringrequiredSHA256 signature

Response

FieldTypeDescription
order_idstringOrder identifier
statusinteger
0 — failed1 — successful
amountnumberAmount charged
curl https://allpay.to/app/?show=runauthorizedpayment&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "your_login",
    "order_id": "J5-001",
    "amount": 450.00,
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login'    => 'your_login',
  'order_id' => 'J5-001',
  'amount'   => 450.00  // charge less than reserved
];
$body['sign'] = allpay_sign($body, 'YOUR_API_KEY');
// POST to https://allpay.to/app/?show=runauthorizedpayment&mode=api12
const body = {
  login: 'your_login', order_id: 'J5-001',
  amount: '450.00'
};
body.sign = allpaySign(body, 'YOUR_API_KEY');
const { status } = await (await fetch('https://allpay.to/app/?show=runauthorizedpayment&mode=api12', {
  method: 'POST', headers: {'Content-Type': 'application/json'},
  body: JSON.stringify(body)
})).json();

Verify API Credentials

POSThttps://allpay.to/app/?show=checkkeys&mode=api12

Verify that an API login + key pair is valid, without making a payment. Useful for onboarding flows where you're connecting a merchant's account.

Parameters

NameTypeDescription
login*stringrequiredAPI login to verify
sign*stringrequiredSHA256 signature generated with the API key

Response (valid credentials)

FieldTypeDescription
last_paid_order_idstringLast paid order ID, or "-1" if none
last_paid_order_datestringUnix timestamp of last payment, or "-1" if none

Response (invalid credentials)

{ "error_code": 3, "error_msg": "Signature is incorrect" }
curl https://allpay.to/app/?show=checkkeys&mode=api12 \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "login": "their_login",
    "sign": "YOUR_COMPUTED_SIGN"
  }'
$body = [
  'login' => 'their_login'
];
$body['sign'] = allpay_sign($body, 'THEIR_API_KEY');
// POST to https://allpay.to/app/?show=checkkeys&mode=api12
// isset($response['error_code']) → invalid credentials
const body = { login: 'their_login' };
body.sign = allpaySign(body, 'THEIR_API_KEY');
const res = await (await fetch('https://allpay.to/app/?show=checkkeys&mode=api12', {
  method: 'POST', headers: {'Content-Type': 'application/json'},
  body: JSON.stringify(body)
})).json();

if (res.error_code) {
  // invalid credentials
} else {
  // valid — res.last_paid_order_id
}

Test Cards

Enable test mode in your account settings, then use the card numbers below. Use any future date as the expiration date and any three digits for the CVV.

Card Numbers

BrandNumberResult
Visa 4557430402053431 ✓ Success
Mastercard 5326105300985846 ✓ Success
American Express 375516193000090 ✓ Success
Any brand 4000000000000002 ✗ Failure simulation
ℹ️ Test mode is enabled in settings of each integration. Real cards are not charged in test mode. This default can be overridden per request with the test_mode parameter in Create Payment.

Changelog

API updates, new endpoints and parameters, and breaking changes — in reverse chronological order.

September 10, 2026 v13

Create Subscription now applies a softer check in test mode. Error 22Subscriptions module is not enabled for this account — is returned for a live subscription when the Subscriptions module has no current paid period; for a test payment (test_mode = 1) the module only has to be switched on, so an integration can be built and tested before the module is paid for. Applies to all API versions that support subscriptions (v7 and later).

September 10, 2026 v12

New Chargeback Webhook. Allpay now notifies your webhook_url when an order is charged back by the card issuer, and again when such a chargeback is reverted. Previously chargebacks were visible only in the merchant dashboard.

type

New field that identifies the event: chargeback or chargeback_revert. Regular payment webhooks do not contain type — handlers that ignore payloads carrying this field keep their current behavior.

amount, refunded, order_amount, currency

Amount of the operation, the running total charged back or refunded on the order, and the full charged amount of the order — all in the currency the card was charged in.

Delivery, retries and the sign calculation are identical to the Payment Webhook. No webhook is sent for a refund you issue yourself. Applies to all API versions and to payment links with a webhook configured.

August 28, 2026 v12

The Check Payment Status response now includes a new field for partially refunded payments.

refunded

Refunded part of the payment. Returned only when status is 4 (partial refund). Applies to API v8 and later.

August 20, 2026 v12

Added new error code 22Subscriptions module is not enabled for this account. Create Subscription now checks that the Subscriptions module is active for the account before creating the payment; previously such a request returned a payment_url that the customer could not pay. Test payments (test_mode = 1) are unaffected. Applies to all API versions that support subscriptions (v7 and later).

August 19, 2026 v12

Clarified in the Create Subscription docs that start_date / end_date only select a calendar day — charges run via a once-daily batch job, so the time-of-day portion of the timestamp does not control the exact moment of the charge. No API behavior changed; this is a documentation clarification. Applies to all API versions.

August 19, 2026 v12

Webhooks that report a saved card rather than a charge now say so explicitly. This affects subscription creation with any deferred start_type and Capture Token. Both previously sent status = 1 with the full price in items and no amount field, which could be mistaken for a completed payment.

amount

Now always present and set to 0 in these webhooks.

subscription_create

New field, present only in these webhooks: 1 — subscription created and the first charge scheduled; 0 — card saved without creating a subscription. Webhooks reporting an actual charge do not include this field.

Both fields are included in the sign calculation. If you verify signatures over the received payload — as described in Signature — no change is required on your side. Applies to all API versions.

July 17, 2026 v12

Fixed subscription completion for end_type=3 with end_n=1: previously, when the first charge occurred immediately (start_type=1), the subscription stayed active and a second charge was attempted a month later. Now the subscription completes right after the first charge. end_n=1 is fully supported for all start types.

July 6, 2026 v12

The Refund Payment response now includes links to refund documents when they are created (an accounting service — EasyCount or Morning — is connected and the original payment has a receipt).

receipt

Link to the refund receipt (negative receipt).

receipt_tax

Link to the credit tax invoice. Issued only for VAT-registered businesses, which receive two refund documents.

May 25, 2026 v12

Added new error code 21Amount must be at least 5 ILS. Returned when the payment amount (after applying currency rate) is below 5 ILS. Previously this case was not enforced via the API.

May 16, 2026 v12

API v12 released: support for donation receipts and donation payment buttons.

In light of the new reporting requirements for non-profit organizations in Israel, Allpay API v12 now supports two new parameters for payment creation.

doc_type

Document type for the document issued after payment. If not provided, the default value is taken from your account settings.

Available values: 320 — Tax Invoice Receipt, 400 — Receipt, 405 — Receipt for donation.

button_title

Text displayed on the payment button. Available values: pay (default), donate, subscribe.

This update allows non-profit organizations to create payments that issue the correct donation document and display a more suitable payment button for donation flows.

April 10, 2026 v11

API v11 released. We've introduced several updates to improve flexibility and control over payments and card handling.

New capturetoken endpoint

Allows saving a customer's card without charging it. Works with both redirect flow and Hosted Fields.

Webhook error notifications

Webhook notifications are now sent to webhook_url in case of payment errors. The customer remains on the payment page, allowing them to retry with another card.

Webhook delivery and retries

Your server must return an HTTP 200 OK response to confirm successful receipt of a webhook. If any other status is returned, or the request fails due to a timeout or network error, Allpay will automatically retry delivery.

Allpay performs up to 10 delivery attempts in total. The first retry is made 1 minute after the initial failure. Subsequent retries are sent with progressively increasing intervals, with the final attempt occurring within 24 hours of the original request. If all delivery attempts fail, the webhook will be marked as failed and no further retries will be made.

Custom payment button text

You can now customize the payment button label using the new button_title parameter. Available options: "Pay" or "Donate".

January 22, 2026

The notifications_url parameter has been renamed to webhook_url. notifications_url remains valid and fully supported for all API versions below v10.

January 16, 2026 v10

We've released API v10, introducing the new currency_display parameter. This parameter allows you to display prices to customers in one currency while charging in the billing currency. It helps show prices in a familiar currency for customers, while keeping settlement and payouts in the merchant's preferred currency.

No changes are required if you do not need multi-currency price display.

November 20, 2025 v9

API version 9 introduces support for item-level discounts. Two new optional parameters have been added: discount_val — discount amount for the item, and discount_type — defines whether the discount is a fixed amount or a percentage. These parameters allow displaying the discount directly on the payment page and automatically deducting it from the item price.

August 25, 2025

Added new value 4 — partially refunded to the payment status parameter in responses to Refund requests and Payment status verification requests.

July 25, 2025

Added API Keys Verification endpoint that allows developers of various platforms integrating with Allpay to verify the validity and authenticity of a user's Allpay API login and key without initiating a payment.

July 15, 2025

Added support for partial refunds by introducing the optional items array in the refund request.

May 8, 2025

Introducing New J5 Transaction Flow. J5 is a two-step payment process used in Israeli payment systems. It begins with a pre-authorization (reservation) of funds on a customer's card for up to 168 hours (7 days). During this time, you can charge the reserved amount — fully or partially. If no charge is made, the funds are automatically released.

This is applicable for use cases like deliveries, rentals, variable-weight goods, or custom orders. Read more about J5 →

March 12, 2025

Allpay introduces Hosted Fields — a secure way to embed a payment form on a website or in an application, fully adapting it to your design. Tutorial →

February 13, 2025

Added a new parameter show_applepay to the payment request, allowing control over the Apple Pay button visibility on the payment page. The Apple Pay module must be activated in your account first. This parameter is useful in order to hide the button when creating a card token, as Apple Pay payments cannot be used for tokenization.

January 29, 2025

We're introducing two new tools for developers to test payments via API:

Allpay API Tester

With the Allpay API Tester, you can send requests for new payments, refunds, subscriptions, and other operations in both live and test modes, simulating requests from your server.

API Tag

Every transaction processed via the API is marked with an "API" tag in the Allpay dashboard. Clicking on the tag allows you to view the associated API request and response.

November 22, 2024

Language support updates. New lang parameter values:

AUTO — automatically sets the payment page language based on the client's browser settings. This is now the default value.

AR — added support for Arabic language.

If the lang parameter is not provided or set to AUTO, the payment page will automatically display in the client's browser language. Providing EN, RU, HE, or AR will display the payment page in that language for all clients, regardless of their browser settings.

A language switcher is now available on the payment page, allowing clients to change the language at any time, regardless of the initial lang parameter setting.

November 15, 2024 v6

API updated to version 6.

New parameters introduced

items — an array containing product details, including names, quantities, prices, and VAT attributes. This information will appear in the Allpay app and in the digital invoice if digital invoice integration is enabled.

expire — a Unix timestamp that defines the lifetime of the payment link. Once the link expires, it becomes invalid for payment. This helps avoid situations where customers pay for products or services that are no longer available.

Removed parameters

name (product name) and amount (total payment amount).

Key changes

The items array replaces the need for the name and amount parameters. The final amount is calculated based on the prices and quantities provided in the items array. Using the vat parameter inside the items array, Allpay will either display the VAT amount on the payment page or indicate that VAT is not included.

Important: Prices provided in the items array must already include VAT (if applicable). The vat parameter is used only to specify whether VAT is included in the item's price or not. We do not add VAT on top of the prices.

The old API version will continue to function as before.

October 6, 2024

Added support for full or partial refunds via the API. See the Refund endpoint.

August 3, 2024

The new payment request parameter show_bit allows you to enable or disable the display of the Bit payment button on the payment page. The Bit module must be activated in your Allpay account first.

March 14, 2024

The receipt parameter is included in both payment notification and payment verification response. This parameter provides the URL to the digital receipt, which is generated by the EasyCount module when the module is activated in the account settings.

Please note that the request URL changed to ...api4.

February 9, 2024

Added new optional parameter for Payment Request: client_tehudat, representing the client's Social ID Number (Teudat Zehut). If provided, Allpay won't prompt the client for manual entry. If not provided, it will be requested on the payment page, as required by law. For non-Israeli citizens, submit 000000000.

December 24, 2023

fail_url parameter will no longer be applied because payment errors are displayed directly on the payment page, prompting the customer to make a new payment attempt.

New parameter added: backlink_url — a URL for the new "Return to site" button on the bottom of the payment page.

December 21, 2023

New parameters added in the responses for payment protocol, status verification and token requests: card_mask (example: 465901******7049), card_brand (example: Visa, Mastercard etc.) and foreign_card (issued in Israel or abroad).

Request URLs changed from ...api1 to ...api2.

September 9, 2023

Added endpoint for creating and using tokens.

June 30, 2023

When submitting the currency parameter in USD or EUR, the amount will be auto-converted to ILS on the Allpay side. Exchange rates are taken in real time from Google Finance.

June 29, 2023

Added payment verification method to check transaction status.

Resources & Support

Tools, guides, and contact information to help with your integration.

Tools

API Tester Interactive tool to send API requests and inspect responses without writing code
API Reference for AI models (.md) Machine-readable Markdown version of this reference — feed it to an AI coding assistant (Copilot, Claude, Codex, etc.) to help generate an accurate integration
Hosted Fields Embed a PCI-compliant card input directly in your page without redirecting the customer

Guides

Webhooks Guide How to configure per-integration webhook URLs — in addition to the webhook_url passed per request, you can set a fixed URL in your integration settings that Allpay will also notify after every payment
API Q&A Answers to the most common integration questions
Currencies List All supported currencies and their codes for currency / currency_display
J5 / Pre-auth Guide In-depth explanation of the two-step pre-authorization flow
Token UI Recommendations UX guidelines for building a saved-card interface using tokens

Support & Updates

[email protected] Technical support over email
@allpay_israel Technical support over Telegram
@allpay_api Telegram channel to track API updates