-
Notifications
You must be signed in to change notification settings - Fork 0
Supported Gateways
Twenty-five gateways, all implemented and covered by tests.
| Gateway | Constant | Protocol | Redirect | Verify | Refund | Inquiry | Callback | Split |
|---|---|---|---|---|---|---|---|---|
| Zarinpal | payvand.Zarinpal |
REST | GET | ✅ | ➖ | ✅ | ✅ | ✅ |
| Zibal | payvand.Zibal |
REST | GET | ✅ | ➖ | ✅ | ✅ | ✅ |
| Vandar | payvand.Vandar |
REST | GET | ✅ | ✅ | ➖ | ✅ | ➖ |
| PayWeb | payvand.PayWeb |
REST | GET | ✅ | ➖ | ➖ | ✅ | ➖ |
| IDPay | payvand.IDPay |
REST | GET | ✅ | ➖ | ✅ | ✅ | ➖ |
| Pay.ir | payvand.PayIr |
REST, form | GET | ✅ | ➖ | ➖ | ✅ | ➖ |
| NextPay | payvand.NextPay |
REST | GET | ✅ | ✅ | ➖ | ✅ | ➖ |
| PayPing | payvand.PayPing |
REST | GET | ✅ | ➖ | ➖ | ✅ | ➖ |
| BitPay.ir | payvand.BitPay |
REST, form | GET | ✅ | ➖ | ➖ | ✅ | ➖ |
| YekPay | payvand.YekPay |
REST | GET | ✅ | ➖ | ➖ | ✅ | ➖ |
| Sadad · Bank Melli | payvand.Sadad |
REST + 3DES | GET | ✅ | ➖ | ➖ | ✅ | ➖ |
| Parsian | payvand.Parsian |
SOAP | GET | ✅ | ✅ | ➖ | ✅ | ✅ |
| Iran Kish | payvand.IranKish |
REST + RSA/AES | POST | ✅ | ➖ | ➖ | ✅ | ➖ |
| Mellat · Behpardakht | payvand.Mellat |
SOAP | POST | ✅ | ✅ | ✅ | ✅ | ➖ |
| Saman · SEP | payvand.Saman |
REST | GET | ✅ | ✅ | ➖ | ✅ | ➖ |
| Pasargad | payvand.Pasargad |
REST + RSA sign | GET | ✅ | ✅ | ✅ | ✅ | ➖ |
| AsanPardakht | payvand.AsanPardakht |
REST v1 | POST | ✅ | ✅ | ✅ | ✅ | ✅ |
| Sepehr · Bank Saderat | payvand.Sepehr |
REST | POST | ✅ | ✅ | ➖ | ✅ | ➖ |
| TOP | payvand.Top |
REST, in-app | in-app | ✅ | ➖ | ✅ | ➖ | ➖ |
| Jibit · PPG v3 | payvand.Jibit |
OAuth REST | GET | ✅ | ✅ | ✅ | ✅ | ➖ |
| SnappPay | payvand.SnappPay |
OAuth REST, BNPL | GET | ✅ | ✅ | ✅ | ✅ | ➖ |
| TorobPay | payvand.TorobPay |
OAuth REST, BNPL | GET | ✅ | ✅ | ✅ | ✅ | ➖ |
| Digipay | payvand.DigiPay |
OAuth REST, wallet/BNPL | GET | ✅ | ✅ | ➖ | ✅ | ✅ |
| Tara | payvand.Tara |
OAuth REST, club credit | POST | ✅ | ➖ | ➖ | ✅ | ✅ |
| Virtual | payvand.Virtual |
in-memory | GET | ✅ | ✅ | ✅ | ✅ | ➖ |
➖ means the provider exposes no such API to merchants. The call returns
payvand.ErrNotSupported, and Capabilities() reports it before you call.
Terminals are configured in Rial or Toman; pin yours with
zarinpal.WithCurrency. A description is mandatory, so Payvand falls back to
zarinpal.WithDefaultDescription and finally to "Payment <order id>".
Code 101 on verification means "already verified" and is treated as success.
Refunds exist only in the merchant panel.
Sandbox mode replaces the merchant id with the literal zibal. Supports both
amount based and percentage based split settlement, fee modes and
mobile/card matching.
Two calls are needed to settle: the transaction endpoint then the verify
endpoint. Skipping the second one lets Vandar roll the payment back. Refunds
use the separate business API (api.vandar.io), so MerchantID must carry
the business name.
Bearer authenticated. The code returned by the create endpoint is both the
token and the gateway query parameter.
OrderID is mandatory and is part of the verification key. Status 10 means
paid but not verified — that is the state a callback arrives in. 100, 101 and
200 all mean settled.
Form encoded. The sandbox uses the reserved API key test. The factor number
is optional; enable it with payir.WithOrderAsFactorNumber to make payments
searchable by order id in the panel.
Success is code -1 on the token endpoint and 0 everywhere else — a provider quirk, not a typo. Refunds reuse the verification endpoint with the refund flag set.
Works in Toman. Pass any unit; Payvand converts. Verification is keyed on the
refid of the callback, not on the token returned at purchase.
The send endpoint answers with a bare number: positive is the payment id,
negative is an error code (bitpay.Message decodes them). Verification needs
both id_get and the trans_id from the callback.
Multi-currency. Set the ISO 4217 numeric pair with yekpay.WithCurrencies
(CurrencyIRR, CurrencyEUR, CurrencyUSD, CurrencyGBP, CurrencyTRY).
Rial amounts are sent as Rial; other currencies are sent as the major unit.
Every call carries a 3DES-ECB signature: terminal;order;amount for the
purchase, the token for the verification. MerchantKey is the base64 terminal
key. OrderID must be numeric.
Two services: the plain sale, and the multiplexed sale with IBAN shares.
Enable the second with parsian.WithMultiplexing or
parsian.WithSettlementToIBAN. Reversal is supported and works within the
provider's reversal window.
Purchase builds an authentication envelope: a one-time AES-128 key encrypts
terminal + password + amount, and the key plus the SHA-256 of the cipher
text are sealed with the acquirer's RSA public key. Confirmation needs the
trio (token, retrieval reference number, system trace audit number) — all
three arrive with the callback. Redirect is a POST form.
SOAP. Verify runs bpVerifyRequest and bpSettleRequest, because an
unsettled transaction is reversed by the bank; use mellat.WithoutSettle only
if you settle in a separate batch. Refund maps to bpReversalRequest,
inquiry to bpInquiryRequest. The pay request answers "0,RefId", and the
payer is posted to startpay.mellat.
The token call is a single endpoint with an action field. The callback posts
State, Status, RefNum, ResNum and the masked PAN. Verification and
reversal are keyed on RefNum.
Every body is RSA signed into the Sign header. The invoice date must be
identical between purchase and verification, so it comes back in
PurchaseResponse.Extra[pasargad.InvoiceDateKey] — store it with the order.
Verify checks the transaction first (CheckTransactionResult) and refuses an
amount that does not match.
Three steps inside Verify: read the transaction, verify it, settle it. The
token endpoint answers with a bare quoted JSON string. Refund reverses a
settled transaction, or cancels an unsettled one with
asanpardakht.WithCancelInsteadOfReverse. Split settlement is supported
through WithSettlements.
Settlement ("advice") is keyed on the digital receipt that arrives with the
callback, not on the purchase token. Callback.VerifyRequest carries it over
for you. A Duplicate advice is treated as success. Rollback is the refund.
In-app: the payer pays inside the TOP application, so there is no redirect URL
and no HTTP callback — ParseCallback returns ErrNotSupported and
Capabilities().Callback is false. OrderID must be a unique number. An
unconfirmed transaction is refunded automatically about thirty minutes later.
top.WithSetData enables the optional post-confirmation payload.
Not an acquirer: Jibit switches the payment to one of several PSPs, so the
payer is redirected to a pspSwitchingUrl. The API key and the secret key
(MerchantKey and Password) are exchanged for a bearer token that Payvand
caches and renews. A purchase that is not verified within fifteen minutes
expires, and ALREADY_VERIFIED comes back as payvand.ErrAlreadyVerified.
The minimum amount is 5,000 Rial. Partial refunds are supported; Reverse
returns a payment that was taken but never verified.
Buy now, pay later. Call Eligible before you show the option: eligibility
depends on the merchant contract and the amount. A cart is mandatory —
snapppay.WithCartBuilder sends your real lines, and the default builder
sends one line for the whole order. Verify runs verify and settle,
because an unsettled payment is reverted; defer the second call with
snapppay.WithAutoSettle(false) and run Settle yourself. Refund maps to
revert, Inquiry to status, and Cancel frees the credit of an abandoned
basket. Mobile numbers are converted to the +98… form the provider wants.
Four interest-free instalments, same shape as SnappPay minus the eligibility
call and the separate settlement. The payment method type is ONLINE_CREDIT.
The cart field names follow TorobPay's own mixed spelling, which is why the
torobpay.Cart type is not shared with snapppay.Cart.
One API for five products, selected with digipay.WithTicketType:
TypeIPG, TypeCredit, TypeWallet (the default), TypeBNPL and
TypeCreditCard. The type travels as a query parameter on every call, and
Verify prefers the type reported by the callback, so a payer who switched
product inside the Digipay app is still verified against what actually paid.
OrderID becomes providerId and must be unique. Refunds need their own
unique providerId — pass it as RefundRequest.OrderID — plus an explicit
amount. Reverse works for about twenty-five minutes; afterwards use
Refund. Credit and BNPL orders must be reported as shipped with Deliver
before Digipay collects the instalments. There is no purchase inquiry, only
RefundStatus.
Pays from a club credit tied to the payer's mobile number, which is
therefore mandatory. The credit is granted per product group, so the invoice
lines carry a group code — set yours with tara.WithDefaultGroup or build the
real lines with tara.WithInvoiceBuilder. tara.WithServiceID routes the
amount to one of the merchant's services. The redirect is a POST form
carrying the user name and the token, which Redirect.Send handles. Refunds
and inquiries are panel-only.
Not a provider: an in-memory gateway for development and tests. It runs the whole purchase → callback → verify → refund cycle offline, and can be told to decline everything or to fail verification.
Next: Configuration · Options
Payvand · MIT licensed · built on the Go standard library alone · report an issue