-
Notifications
You must be signed in to change notification settings - Fork 0
FAQ
Payment code lives long and is audited often. A package that pulls a SOAP
library, an HTTP client and a logger drags their CVEs, their release cadence
and their opinions into your service. Everything Payvand needs — SOAP
envelopes, 3DES, AES, RSA, retries — fits comfortably in the standard library,
so it stays there. CI fails the build if a require block ever appears in
go.mod.
1.26 or newer.
Yes. Build one per terminal at start-up and share it across requests.
Whichever you have. payvand.Rial(150_000) and payvand.Toman(15_000) are the
same money, and each gateway converts to what its own API expects — Rial for
most, Toman for PayPing, either for Zarinpal depending on the terminal.
Yes. Most Iranian gateways reverse a transaction that is never verified, within
15 to 30 minutes. Callback.Succeeded only says the payer got to the end of
the bank page.
Ask the provider with Inquiry, then verify if it reports the money as taken.
See Callbacks and Verification.
Gateways without an inquiry API have to be reconciled from the provider panel.
Because that provider offers no refund API to merchants — Zarinpal, Zibal,
IDPay, Pay.ir, PayPing, BitPay, YekPay, PayWeb, Sadad, Iran Kish and Tara are
in that group today. Check gw.Capabilities().Refund before offering the
button.
Only in what they need on the way in. SnappPay, TorobPay, Digipay and Tara lend
against the goods, so they want the basket: pass it with
snapppay.WithCartBuilder, torobpay.WithCartBuilder,
digipay.WithBasketBuilder or tara.WithInvoiceBuilder. Leave the option out
and Payvand sends a single line covering the order, which is fine for a top-up
and wrong for a shop. Everything after that — purchase, redirect, callback,
verify, refund — is the interface every other gateway implements.
Yes, if you want the option to appear only when it will work. Eligible takes
an amount and answers with the credit decision plus the instalment plans, which
is also what the provider's brand guidelines ask you to display.
Because it does: purchase returns a ticket, the callback returns a tracking
code, and verification keys on the tracking code. ParseCallback already puts
the tracking code in Callback.Token, so Callback.VerifyRequest(amount) is
correct without any extra work.
Yes. Implement core.Gateway in your own module and call payvand.Register.
See Extending.
Sadad, TOP, Mellat and Sepehr require a numeric, unique order id. Use your order's integer primary key, or a numeric sequence dedicated to payments.
Development, tests and staging. It runs the whole cycle in memory, with options to decline payments or fail verification, so you can exercise the unhappy paths without a terminal.
No. It has no database, no cache and no background goroutine. Tokens, orders and reconciliation are yours.
payvand.WithLogger(payvand.SlogLogger{Logger: slog.Default()}), or any type
with Debug and Error. Every request and response passes through it —
redact before shipping to an aggregator, because the bodies contain terminal
credentials.
Only through the providers' generic transaction types today:
irankish.WithTransactionType, asanpardakht.WithServiceType,
pasargad.WithAction and asanpardakht.WithPaymentID. First class support is
on the Roadmap.
Some Shaparak hosts have historically served incomplete certificate chains. It is off by default, documented as a last resort, and should be scoped to the one gateway that needs it.
Yes, for the whole 1.x line: payvand and payvand/core follow semantic
versioning. Packages under internal/ are not part of the contract.
Open an issue with the raw request and response (credentials redacted) and the date. Iranian PSPs change without notice, and that report is usually enough for a one-commit fix.
Yes: payvand.WithHTTPClient takes any Do(*http.Request) (*http.Response, error),
so bring your own transport.
Payvand · MIT licensed · built on the Go standard library alone · report an issue