Skip to content

Options

Amir Iranmanesh edited this page Jul 31, 2026 · 2 revisions

Options

Everything is configured with functional options, and every provider extra is opt-in: leave an option out and the parameter is simply not sent.

Provider options have the same type as the shared ones (payvand.Option), so they compose in one list:

import "github.com/amiranmanesh/payvand/gateway/zibal"

gw, err := pv.Gateway(payvand.Zibal, cfg,
    payvand.WithSandbox(true),          // shared
    payvand.WithTimeout(15*time.Second),// shared
    zibal.WithFeeMode(1),               // provider specific
    zibal.WithMultiplexing(
        zibal.Share{BankAccount: "IR…", Amount: 90_000},
        zibal.Share{SubMerchantID: "sub-1", Amount: 60_000},
    ),
)

Options given to Client.Gateway are applied after the ones given to payvand.Init, so a call can override an application default.

Shared options

Option Effect
WithTimeout(d) bounds a single gateway call; default 30s
WithHTTPClient(c) any Do(*http.Request) (*http.Response, error) — tracing, proxying, mocking
WithLogger(l) request/response events; payvand.SlogLogger{Logger: …} adapts log/slog
WithSandbox(b) switches providers that have a test environment
WithBaseURL(u) overrides the provider host — sandboxes and tests
WithRetry(n, backoff) retries network errors and 5xx responses, doubling the pause
WithHeader(k, v) an extra header on every request
WithUserAgent(ua) overrides the User-Agent
WithSkipTLSVerify(b) last resort for a Shaparak host with an incomplete chain

Provider options

gateway/zarinpal

Option Effect
WithCurrency(c) pins the unit sent to Zarinpal, for Toman terminals
WithWages(…) split settlement between IBANs
WithDefaultDescription(s) used when a request carries no description (Zarinpal requires one)

gateway/zibal

Option Effect
WithLedger(id) routes settlement to a specific ledger
WithFeeMode(n) who pays the fee: 0 merchant, 1 payer, 2 ledger
WithMobileCardCheck(b) the paying card must belong to the mobile number
WithMultiplexing(…) split settlement by amount
WithPercentMultiplexing(…) split settlement by percentage
WithDefaultDescription(s) fallback description

gateway/vandar

Option Effect
WithPort(p) selects a specific IPG port of the business
WithComment(s) comment shown in the Vandar panel
WithAccessToken(t) bearer token of the business API, needed by refunds
WithOrderAsFactorNumber(b) sends the order id as the factor number
WithDefaultDescription(s) fallback description

gateway/payweb

Option Effect
WithDefaultComment(s) fallback comment
WithCardRestriction(b) forwards the first AllowedCards entry, restricting the payment to that card

gateway/idpay, gateway/bitpay

Option Effect
WithDefaultDescription(s) fallback description

gateway/payir

Option Effect
WithOrderAsFactorNumber(b) sends the order id as the factor number
WithDefaultDescription(s) fallback description

gateway/nextpay

Option Effect
WithCurrency(c) pins the unit sent to NextPay
WithAutoVerify(b) lets NextPay verify the transaction itself
WithDefaultDescription(s) payer description

gateway/payping

Option Effect
WithPayerIdentity(s) identity on the receipt; defaults to the request mobile or email
WithDefaultDescription(s) fallback description

gateway/yekpay

Option Effect
WithCurrencies(from, to) ISO 4217 numeric pair; defaults to Rial in, Rial out
WithAddress(s) payer address, when the contract requires it
WithDefaultDescription(s) fallback description

gateway/sadad

Option Effect
WithApplicationName(s) merchant application name shown to the payer
WithAdditionalData(s) free text kept with the transaction
WithMobileAsUserID(b) sends the mobile as Sadad's UserId, offering saved cards

gateway/parsian

Option Effect
WithMultiplexing(shares…) switches to the multiplexed service and splits by IBAN
WithSettlementToIBAN(b) multiplexed service, full amount to Config.IBAN
WithAdditionalData(s) free text kept with the transaction
WithMobileAsOriginator(b) sends the mobile as the originator

gateway/irankish

Option Effect
WithTransactionType(s) overrides "Purchase" — bills and top-ups use their own values
WithMobileAsCmsID(b) sends the mobile as the CMS preservation id

gateway/mellat

Option Effect
WithAdditionalData(s) free text kept with the transaction
WithPayerID(s) Mellat payer identifier; "0" when unset
WithoutSettle(b) skips bpSettleRequest inside Verify — only if you settle separately

gateway/saman

Option Effect
WithGetMethod(b) asks SEP to return the payer with a GET instead of a POST form
WithMobile(b) sends the mobile so the page offers saved cards

gateway/pasargad

Option Effect
WithAction(s) overrides the action code; "1003" is a purchase
WithPayerDetails(b) sends the payer mobile and email
WithoutTransactionCheck(b) skips CheckTransactionResult before settling

gateway/asanpardakht

Option Effect
WithServiceType(n) overrides the service type id; 1 is a purchase
WithPaymentID(s) bill payment identifier
WithSettlements(…) split settlement between IBANs
WithAdditionalData(s) free text kept with the transaction
WithoutSettlement(b) skips the settlement call inside Verify
WithCancelInsteadOfReverse(b) Refund calls Cancel — only valid before settlement

gateway/sepehr

Option Effect
WithPayload(s) free field echoed back with the callback
WithPayerDetails(b) sends the mobile and national code

gateway/top

Option Effect
WithAdditionalInfo(s) free text kept with the transaction
WithUserID(s) identifies the payer when no mobile is available
WithSetData(d) enables the post-confirmation SetData push (once per transaction)

gateway/virtual

Option Effect
WithDecline(b) every payment comes back declined
WithRedirectURL(u) sends the payer to a page of your own instead of the callback
WithFailingVerify(b) verification always fails, to exercise the recovery path

Writing an option of your own

Provider options are ordinary functions over *core.Options, so nothing stops you from writing one in your own code — for example a logger that redacts:

func withRedactedLogging(l payvand.Logger) payvand.Option {
    return func(o *payvand.Options) { o.Logger = l }
}

Next: Errors · Testing

Clone this wiki locally