deepayment

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

README

DEEPayment SDK for Go

Go SDK for the merchant open API. English | 简体中文

Requests are signed with the merchant's Ed25519 key (RFC 9421 HTTP Message Signatures). POST bodies are sealed to the platform's X25519 public key (libsodium sealed box). Signing, digesting and sealing are handled by the SDK. NewClient rejects non-HTTPS BaseURLs. Synchronous responses remain plaintext JSON and rely on HTTPS/TLS for confidentiality and integrity.

0. Installation

go get github.com/deepayment/sdk-go

Go 1.24 or newer. The only third-party dependency is golang.org/x/crypto.

1. Usage

import deepayment "github.com/deepayment/sdk-go"

c, err := deepayment.NewClient(deepayment.Config{
    BaseURL:                     "https://panama.deepayment.com",     // production origin; no /api/v1
    AccessKey:                   "mak_live_xxx",
    MerchantPrivateKeyBase64:    merchantPrivateKey,            // merchant Ed25519 private key, base64
    PlatformBodyKeyID:           "body_20260827_01",
    PlatformBodyPublicKeyBase64: platformBodyPublicKey,         // platform X25519 public key, base64
    PlatformWebhookPublicKeys:   platformWebhookPublicKeys,     // keyID -> base64 Ed25519 public key
})
if err != nil { return err }

order, err := c.CreatePayment(ctx, &deepayment.CreatePaymentReq{
    MerchantOrderNo: "M20260101001",
    Currency:        deepayment.CurrencyBRL,
    Amount:          "100.00",                                  // decimal string, never a JSON number
    PaymentMethod: deepayment.PaymentMethod{
        Code: deepayment.MethodCodePIX,
        Pix:  &deepayment.PaymentPixExtra{PayerName: "Joao Silva"},
    },
    WebhookUrl: "https://merchant.example/webhook/payments",
})

// Error handling
var apiErr *deepayment.APIError
var respErr *deepayment.ResponseError
switch {
case errors.As(err, &apiErr):  // business error (envelope decoded)
    log.Printf("api error: %s %s (trace=%s)", apiErr.Msg, apiErr.Message, apiErr.TraceID)
case errors.As(err, &respErr): // infrastructure error (gateway/CDN returned a non-envelope body)
case err != nil:               // transport error
}

Keys are the merchant's responsibility: the merchant generates its own Ed25519 key pair and shares only the public key with the platform. The platform never receives or stores the merchant private key.

ARS payments and payouts

ARS payments use BANK_TRANSFER / BankTransfer, CVU / Cvu, or QRIS / Qris. All three require FirstName, LastName, Email, DocumentType (DNI/CUIT), and DocumentNumber. CVU and QRIS also require Phone: 10 digits, with a nonzero first digit. BANK_TRANSFER does not require a phone. The identity and account details below are fictional; replace them with the actual customer details.

order, err := c.CreatePayment(ctx, &deepayment.CreatePaymentReq{
    MerchantOrderNo: "ars-cvu-demo-001", Currency: deepayment.CurrencyARS, Amount: "1000.00",
    PaymentMethod: deepayment.PaymentMethod{
        Code: deepayment.MethodCodeCVU,
        Cvu: &deepayment.PaymentArsDocumentExtra{
            FirstName: "Ana", LastName: "Perez", Email: "ana@example.com", Phone: "1123456789",
            DocumentType: "DNI", DocumentNumber: "30123456",
        },
    },
    WebhookUrl: "https://merchant.example.com/webhook",
})

Redirect the payer to the channel checkout at order.Action.Url. Select each method explicitly; they do not switch automatically. Opening the checkout or returning to your site does not confirm payment. Use order queries or verified platform webhooks.

ARS payouts use BANK_TRANSFER. Set AccountType to the string "CBU" or "CVU", and keep AccountNo as a digit string to preserve leading zeros. The same phone format applies. The eight other recipient fields are required; Address is optional. Omission, null and an empty string all mean no address; non-empty strings are preserved, and numbers, booleans, arrays and objects are rejected. The typed Go field omits an empty string; SetExtra can supply an explicit null or empty string. DocumentType and DocumentNumber must not be empty:

order, err := c.CreatePayout(ctx, &deepayment.CreatePayoutReq{
    MerchantOrderNo: "ars-payout-demo-001", Currency: deepayment.CurrencyARS, Amount: "1000.00",
    PayoutMethod: deepayment.PayoutMethod{
        Code: deepayment.MethodCodeBankTransfer,
        BankTransfer: &deepayment.PayoutBankTransferExtra{
            FirstName: "Ana", LastName: "Perez", Email: "ana@example.com", Phone: "1123456789",
            Address: "Av Example 123", DocumentType: "DNI", DocumentNumber: "30123456",
            AccountNo: "0000003100012345678901", AccountType: "CBU", // "CVU" is also supported
        },
    },
    WebhookUrl: "https://merchant.example.com/webhook",
})

The SDK checks required fields before sending. The gateway validates phone format and account type values. Other currencies retain their own account type rules.

PEN payments and payouts

The executable PEN examples build three payment requests (BANK_TRANSFER, E_WALLET, CASH) and three payout requests (bank transfer, Yape, Plin), using the existing typed fields. They only serialize requests and make no network calls. Run them with go test -run 'ExampleCreate.*Req_pen'.

For wallet payouts, use E_WALLET / EWallet with BankCode 026 for Yape or 025 for Plin. AccountNo identifies the recipient wallet; CustomerPhone is contact information. Bank payouts use BANK_TRANSFER / BankTransfer, with AccountType SAVINGS or CHECKING and a 20-digit CciNo. Keep account numbers as strings. All identity and account details in the examples are fictional; replace them before sending a real request. Method availability depends on your merchant configuration.

Two kinds of failure, opposite handling
Error Meaning Action
errors.Is(err, ErrInvalidRequest) Rejected before it was sent (local validation, a bad parameter, or a request the SDK could not encode or sign) Safe to mark failed; fix the request and retry under the same merchantOrderNo
errors.Is(err, ErrTransport) Handed to the transport, no usable response (connection failure, timeout, interrupted read) Outcome unknown; never mark a payout failed. Query by merchantOrderNo, or resend the identical request under the same number
*APIError The gateway returned a business error (Msg / Message / TraceID) Branch on msg. IDEMPOTENCY_CONFLICT: the number is taken but the platform could not return its order, query that number and keep querying rather than switching numbers. CHANNEL_ERROR: the order may already exist, query by merchantOrderNo first and reuse that number only once the query returns ORDER_NOT_FOUND. CHANNEL_BUSY: refused before the order was created, so resend the same number after a back-off; this is the only channel error that needs no query first
*ResponseError The gateway or CDN returned something that is not an envelope (HTML 502, ...) Outcome unknown; query before deciding
errors.Is(err, ErrResponseTooLarge) A response arrived but exceeded the size limit and was discarded Outcome unknown; the order was most likely created, query before deciding
Anything else An unexpected error; assume the request may have arrived Outcome unknown; query before deciding

merchantOrderNo is the only key that prevents a duplicate order. A second create with the same number never creates a second order: the platform answers with the original order, or with IDEMPOTENCY_CONFLICT when it recognises the number as taken but cannot return that order. The idempotency key travels with the request for tracing and is not a deduplication key.

Two rules follow:

  • After an unknown outcome, never allocate a new merchantOrderNo. Query the existing one, or resend the same request under the same number.
  • A resend must carry identical parameters. The platform returns the original order without comparing fields, so a changed amount or account silently has no effect. To change anything, use a new merchantOrderNo and reconcile the original order first.

The SDK validates locally before signing (top-level required fields and formats, method shape and required extras); the rules are defined in protocol/merchant-api.md. Format checks (phone length, e-mail, …) stay with the gateway on purpose.

2. Idempotency and retries

Write calls are not retried automatically. On a timeout, recover by querying the order via merchantOrderNo or orderNo. Retry safety comes from reusing the same merchantOrderNo, not from the idempotency key: the key is carried for tracing only. The SDK regenerates the request nonce on every attempt, so calling the same method again is a valid retry while replaying captured bytes is not.

order, err := c.CreatePayment(ctx, req, deepayment.WithIdempotencyKey(key))

3. Webhook

wh, err := c.ParsePaymentWebhook(r)  // strict orderType=PAYMENT; mismatch -> ErrInvalidWebhookBody
// or
wh, err := c.ParsePayoutWebhook(r)   // strict orderType=PAYOUT

Verification order: nil check -> shape -> Content-Digest over the body -> Webhook-Event-Id matches the body eventId -> platform Ed25519 signature by the keyid in Signature-Input. Signatures are fresh for a short window, so the platform re-signs every delivery attempt. Deduplicate delivery side effects by eventId, make order state updates idempotent by orderNo or merchantOrderNo, and return 2xx on success or the platform retries.

Failure fields (present when status=FAILED)

Both webhooks and order queries return failure. Branch on failure.msg; failure.message is for display and troubleshooting only.

if wh.Status == "FAILED" && wh.Failure != nil {
    switch wh.Failure.Msg {
    case deepayment.MsgChannelError:        // the order may already exist; requery by merchantOrderNo, do not reissue
    case deepayment.MsgOrderRejected:       // risk/business rejection
    case deepayment.MsgInsufficientBalance:
    }
}

Full error-code table: protocol/errors.md.

4. Amounts

Amount, PaidAmount, balances, fees and rates are decimal strings such as "100.50", never JSON numbers. Keep amounts as strings end to end; do not parse them into float64.

5. Unlisted methods

m := deepayment.PaymentMethod{Code: "NEW_METHOD"}
_ = m.SetExtra("newMethod", map[string]any{"customerName": "X", "bankCode": "001"})

6. Protocol and test vectors

protocol/ is the cross-language source of truth: the signature wire spec, the sealed-box envelope spec, and fixed test vectors.

7. Development

go test -race ./...       # full test suite

Documentation

Overview

Package deepayment is the Go SDK for the merchant open API.

Requests are signed with the merchant's Ed25519 key using RFC 9421 HTTP Message Signatures; POST bodies are sealed to the platform's X25519 public key (libsodium sealed box). Signing, digesting and sealing are handled transparently; callers deal with typed requests and responses.

c, err := deepayment.NewClient(deepayment.Config{
    BaseURL:                     "https://panama.deepayment.com",
    AccessKey:                   "mak_live_xxx",
    MerchantPrivateKeyBase64:    merchantPrivateKey,
    PlatformBodyKeyID:           "body_20260827_01",
    PlatformBodyPublicKeyBase64: platformBodyPublicKey,
    PlatformWebhookPublicKeys:   platformWebhookPublicKeys,
})
order, err := c.CreatePayment(ctx, &deepayment.CreatePaymentReq{...})

Amounts, balances, fees and rates are decimal strings, never JSON numbers. Write APIs are not retried automatically; recover from timeouts by querying the order via merchantOrderNo or orderNo. A deliberate retry reuses the same merchantOrderNo, which is the only key the platform deduplicates on; the idempotency key is carried for tracing only. The wire protocol is documented under protocol/ and the shared conformance vectors under protocol/testdata.

Index

Examples

Constants

View Source
const (
	StatusPending    = "PENDING"
	StatusProcessing = "PROCESSING"
	StatusSucceeded  = "SUCCEEDED"
	StatusFailed     = "FAILED"
	StatusExpired    = "EXPIRED"
	StatusCanceled   = "CANCELED"
	StatusRefunded   = "REFUNDED"
)

Public order statuses. REFUNDED applies only to a returned payout after its refund has been credited; payment and checkout statuses are unchanged.

View Source
const (
	CurrencyBRL = "BRL"

	CurrencyARS = "ARS"
	CurrencyMXN = "MXN"
	CurrencyCOP = "COP"
	CurrencyCLP = "CLP"
	CurrencyPEN = "PEN"
	CurrencyTRY = "TRY"
	CurrencyRUB = "RUB"
	CurrencyUSD = "USD"
	CurrencyBDT = "BDT"
	CurrencyIDR = "IDR"
	CurrencyPHP = "PHP"
	CurrencyPKR = "PKR"
	CurrencyTHB = "THB"
	CurrencyINR = "INR"
)

Currency codes accepted by the API; unlisted values pass through unchanged.

View Source
const (
	CountryBR = "BR"

	CountryAR = "AR"
	CountryMX = "MX"
	CountryCO = "CO"
	CountryCL = "CL"
	CountryPE = "PE"
	CountryTR = "TR"
	CountryRU = "RU"
	CountryUS = "US"
	CountryBD = "BD"
	CountryID = "ID"
	CountryPH = "PH"
	CountryPK = "PK"
	CountryTH = "TH"
	CountryIN = "IN"
)
View Source
const (
	MethodCodePIX = "PIX"

	MethodCodePagoFacil       = "PAGO_FACIL"
	MethodCodeRapipago        = "RAPIPAGO"
	MethodCodeBankTransfer    = "BANK_TRANSFER"
	MethodCodeCVU             = "CVU"
	MethodCodeQRIS            = "QRIS"
	MethodCodeSPEI            = "SPEI"
	MethodCodeOXXO            = "OXXO"
	MethodCodeCash            = "CASH"
	MethodCodePSE             = "PSE"
	MethodCodeNequi           = "NEQUI"
	MethodCodeTransfiya       = "TRANSFIYA"
	MethodCodeBreb            = "BREB"
	MethodCodeWebpay          = "WEBPAY"
	MethodCodeKhipu           = "KHIPU"
	MethodCodeMach            = "MACH"
	MethodCodePago46          = "PAGO46"
	MethodCodeServiFacil      = "SERVIFACIL"
	MethodCodeEWallet         = "E_WALLET"
	MethodCodeCashApp         = "CASH_APP"
	MethodCodePayPal          = "PAYPAL"
	MethodCodeChime           = "CHIME"
	MethodCodeCreditCard      = "CREDIT_CARD"
	MethodCodeApplePay        = "APPLE_PAY"
	MethodCodeGooglePay       = "GOOGLE_PAY"
	MethodCodeNeteller        = "NETELLER"
	MethodCodeSkrill          = "SKRILL"
	MethodCodeUSDTTRC20       = "USDT-TRC20"
	MethodCodeUSDTERC20       = "USDT-ERC20"
	MethodCodeUSDTBEP20       = "USDT-BEP20"
	MethodCodeBDBkash         = "BD_BKASH"
	MethodCodeBDNagad         = "BD_NAGAD"
	MethodCodeIDVA            = "ID_VA"
	MethodCodeIDQRIS          = "ID_QRIS"
	MethodCodeIDDana          = "ID_DANA"
	MethodCodeIDOvo           = "ID_OVO"
	MethodCodeIDGopay         = "ID_GOPAY"
	MethodCodeIDLinkaja       = "ID_LINKAJA"
	MethodCodeIDShopeepay     = "ID_SHOPEEPAY"
	MethodCodePHGcash         = "PH_GCASH"
	MethodCodePHMaya          = "PH_MAYA"
	MethodCodePHGrab          = "PH_GRAB"
	MethodCodePHQRIS          = "PH_QRIS"
	MethodCodePHGcashQR       = "PH_GCASH_QR"
	MethodCodePHMayaQR        = "PH_MAYA_QR"
	MethodCodePHNativeGcash   = "PH_NATIVE_GCASH"
	MethodCodePKJazzcash      = "PK_JAZZCASH"
	MethodCodePKEasypaisa     = "PK_EASYPAISA"
	MethodCodePKJazzcashQrph  = "PK_JAZZCASH_QRPH"
	MethodCodePKEasypaisaQrph = "PK_EASYPAISA_QRPH"
	MethodCodeTHBankCard      = "TH_BANK_CARD"
	MethodCodeTHTruemoney     = "TH_TRUEMONEY"
	MethodCodeTHPromptpay     = "TH_PROMPTPAY"
	MethodCodeBankCard        = "BANK_CARD"
	MethodCodePapara          = "PAPARA"
	MethodCodeP2P             = "P2P"
	MethodCodeSBP             = "SBP"
	MethodCodeIDBankTransfer  = "ID_BANK_TRANSFER"
	MethodCodePHDfWallet      = "PH_DF_WALLET"
	MethodCodePHDfBank        = "PH_DF_BANK"
	MethodCodePKBank          = "PK_BANK"
	MethodCodeTHBankTransfer  = "TH_BANK_TRANSFER"
	MethodCodeINIFSC          = "IN_IFSC"
	MethodCodeINUPI           = "IN_UPI"
)

PaymentMethod.Code / PayoutMethod.Code values. Pay-in and pay-out share one namespace; unlisted values pass through unchanged.

View Source
const (
	MsgUnauthorized        = "UNAUTHORIZED"
	MsgInvalidField        = "INVALID_FIELD"
	MsgUnsupportedCurrency = "UNSUPPORTED_CURRENCY"
	MsgUnsupportedMethod   = "UNSUPPORTED_METHOD"
	MsgInsufficientBalance = "INSUFFICIENT_BALANCE"
	MsgMethodNotEnabled    = "METHOD_NOT_ENABLED"
	MsgOrderNotFound       = "ORDER_NOT_FOUND"
	MsgIdempotencyConflict = "IDEMPOTENCY_CONFLICT"
	MsgRateLimited         = "RATE_LIMITED"
	MsgServiceUnavailable  = "SERVICE_UNAVAILABLE"
	MsgInternalError       = "INTERNAL_ERROR"
	MsgOrderRejected       = "ORDER_REJECTED"
	MsgChannelError        = "CHANNEL_ERROR"
	MsgChannelBusy         = "CHANNEL_BUSY"
)

Machine-readable error identifiers from the gateway's envelope "msg" field. Open set; treat unknown values as opaque strings.

View Source
const (
	WebhookOrderTypePayment = "PAYMENT"
	WebhookOrderTypePayout  = "PAYOUT"
)

Variables

View Source
var (
	ErrMissingBaseURL   = errors.New("sdk: Config.BaseURL is required")
	ErrInvalidBaseURL   = errors.New("sdk: Config.BaseURL must be an absolute origin URL")
	ErrMissingAccessKey = errors.New("sdk: Config.AccessKey is required")

	ErrNilRequest        = fmt.Errorf("%w: request is nil", ErrInvalidRequest)
	ErrInvalidPathParam  = fmt.Errorf("%w: invalid path parameter", ErrInvalidRequest)
	ErrInvalidQueryParam = fmt.Errorf("%w: invalid query parameter", ErrInvalidRequest)
	ErrInvalidExtraField = fmt.Errorf("%w: invalid extra field name", ErrInvalidRequest)
	ErrResponseTooLarge  = errors.New("sdk: response body exceeds MaxResponseBytes")

	// ErrTransport wraps failures after the request left the process (connect,
	// timeout, read). The outcome is unknown: query the order before retrying.
	ErrTransport = errors.New("sdk: transport")

	ErrInvalidWebhookBody = errors.New("sdk: invalid webhook body")

	ErrMissingMethodCode      = fmt.Errorf("%w: paymentMethod.code is required", ErrInvalidRequest)
	ErrConflictingMethodExtra = fmt.Errorf("%w: only one method extra may be set", ErrInvalidRequest)
	ErrMethodExtraMismatch    = fmt.Errorf("%w: method extra does not match code", ErrInvalidRequest)
	ErrMethodNotAvailable     = fmt.Errorf("%w: method is not available for this currency", ErrInvalidRequest)
	ErrMissingRequiredField   = fmt.Errorf("%w: required field is empty", ErrInvalidRequest)
	ErrInvalidAmount          = fmt.Errorf("%w: amount must be a positive decimal string", ErrInvalidRequest)
	ErrInvalidWebhookURL      = fmt.Errorf("%w: webhookUrl must be an absolute https URL", ErrInvalidRequest)

	ErrMissingMerchantPrivateKey        = errors.New("sdk: Config.MerchantPrivateKeyBase64 is required")
	ErrMissingPlatformBodyKeyID         = errors.New("sdk: Config.PlatformBodyKeyID is required")
	ErrMissingPlatformBodyPublicKey     = errors.New("sdk: Config.PlatformBodyPublicKeyBase64 is required")
	ErrMissingPlatformWebhookPublicKeys = errors.New("sdk: Config.PlatformWebhookPublicKeys is required")
	ErrInvalidMerchantPrivateKey        = errors.New("sdk: invalid merchant Ed25519 private key")
	ErrInvalidPlatformBodyPublicKey     = errors.New("sdk: invalid platform X25519 public key")
	ErrInvalidPlatformWebhookPublicKey  = errors.New("sdk: invalid platform webhook Ed25519 public key")
	ErrInvalidIdempotencyKey            = fmt.Errorf("%w: invalid Idempotency-Key", ErrInvalidRequest)
	ErrWebhookPlatformKeyNotFound       = errors.New("sdk: webhook platform key not found")
	ErrWebhookEventIDMismatch           = errors.New("sdk: webhook event id mismatch")
	ErrSignedPostQueryNotAllowed        = fmt.Errorf("%w: signed POST query is not allowed", ErrInvalidRequest)
	ErrSignedGetBodyNotAllowed          = fmt.Errorf("%w: signed GET body is not allowed", ErrInvalidRequest)
	ErrSignedMethodNotSupported         = fmt.Errorf("%w: signed method is not supported", ErrInvalidRequest)
)
View Source
var ErrInvalidRequest = errors.New("sdk: invalid request")

ErrInvalidRequest is the parent of every error raised before a request leaves the process.

A single errors.Is(err, ErrInvalidRequest) separates two failures with opposite handling: a match means the request was never sent and the upstream cannot have accepted it, so the caller may safely mark it failed; anything else (network, timeout, non-envelope response) leaves the outcome unknown, and a payout is never marked failed on it. Treating "never sent" as "unknown" strands a payout in pending, waiting for an upstream order that does not exist: no query and no webhook will ever settle it.

Every error raised before sending wraps this sentinel with %w; an unwrapped one is silently classified by integrators as an unknown outcome.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	HTTPStatus int
	Code       int
	Msg        string
	Message    string
	TraceID    string
	RawBody    []byte
}

APIError is the typed business error decoded from a non-success envelope.

func AsAPIError

func AsAPIError(err error) (*APIError, bool)

func (*APIError) Error

func (e *APIError) Error() string

type AddExtraInfoResult

type AddExtraInfoResult struct {
	Status int64 `json:"status"`
	// OrderStatus is the checkout-facing order status (CREATED / PENDING / …).
	OrderStatus string `json:"orderStatus,omitempty"`
	// PaymentUrl is set once the platform placed the order upstream; the payer
	// is redirected there.
	PaymentUrl string `json:"paymentUrl,omitempty"`
	Message    string `json:"message,omitempty"`
}

AddExtraInfoResult is the answer to AddPaymentExtraInfo; like SubmitTradeNoResult it reports acceptance through Status, not through the error.

func (*AddExtraInfoResult) Ok

func (r *AddExtraInfoResult) Ok() bool

Ok reports whether the platform accepted the extra info.

type Balance

type Balance struct {
	Currency           string `json:"currency"`
	Balance            string `json:"balance"`
	LockBalance        string `json:"lockBalance"`
	PaymentBalance     string `json:"paymentBalance"`
	PaymentLockBalance string `json:"paymentLockBalance"`
	PayoutBalance      string `json:"payoutBalance"`
	PayoutLockBalance  string `json:"payoutLockBalance"`
}

type CheckoutParams

type CheckoutParams struct {
	PayContent string `json:"payContent,omitempty"`
	// Reusable indicates the payment content can stay visible after a successful payment.
	Reusable bool `json:"reusable,omitempty"`
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(cfg Config, opts ...Option) (*Client, error)

func (*Client) AddPaymentExtraInfo

func (c *Client) AddPaymentExtraInfo(ctx context.Context, orderNo, payMethod string,
	extra map[string]string) (*AddExtraInfoResult, error)

AddPaymentExtraInfo completes a "create first, fill in later" order: the merchant may create the payment without payer details, and the H5 checkout page supplies them here, which is what triggers the real upstream order. payMethod and extra may be empty when the order already carries them. Unsigned and unencrypted like SubmitPaymentTradeNo; a nil error is not acceptance, see AddExtraInfoResult.

func (*Client) CreatePayment

func (c *Client) CreatePayment(ctx context.Context, req *CreatePaymentReq, opts ...RequestOption) (*PaymentOrder, error)

func (*Client) CreatePayout

func (c *Client) CreatePayout(ctx context.Context, req *CreatePayoutReq, opts ...RequestOption) (*PayoutOrder, error)

func (*Client) GetBalance

func (c *Client) GetBalance(ctx context.Context, currency string) (*Balance, error)

func (*Client) GetPaymentCheckout

func (c *Client) GetPaymentCheckout(ctx context.Context, orderNo string) (*PaymentCheckout, error)

GetPaymentCheckout is unsigned and unencrypted; /api/v1/payment/checkout is a public endpoint used by the H5 checkout page and callable by the merchant backend for reconciliation.

func (*Client) GetPayoutReceipt

func (c *Client) GetPayoutReceipt(ctx context.Context, orderNo string) (*PayoutReceipt, error)

func (*Client) GetUSDRate

func (c *Client) GetUSDRate(ctx context.Context, currency, payMethod string) (*USDRate, error)

func (*Client) ParsePaymentWebhook

func (c *Client) ParsePaymentWebhook(r *http.Request) (*PaymentWebhook, error)

func (*Client) ParsePayoutWebhook

func (c *Client) ParsePayoutWebhook(r *http.Request) (*PayoutWebhook, error)

func (*Client) QueryPaymentByMerchantOrderNo

func (c *Client) QueryPaymentByMerchantOrderNo(ctx context.Context, merchantOrderNo string) (*PaymentOrder, error)

func (*Client) QueryPaymentByOrderNo

func (c *Client) QueryPaymentByOrderNo(ctx context.Context, orderNo string) (*PaymentOrder, error)

func (*Client) QueryPayoutByMerchantOrderNo

func (c *Client) QueryPayoutByMerchantOrderNo(ctx context.Context, merchantOrderNo string) (*PayoutOrder, error)

func (*Client) QueryPayoutByOrderNo

func (c *Client) QueryPayoutByOrderNo(ctx context.Context, orderNo string) (*PayoutOrder, error)

func (*Client) SubmitPaymentTradeNo

func (c *Client) SubmitPaymentTradeNo(ctx context.Context, orderNo, tradeNo string) (*SubmitTradeNoResult, error)

SubmitPaymentTradeNo reports the upstream trade number (UTR) a payer typed into the H5 checkout page, so the platform can match the transfer to the order. Like GetPaymentCheckout it is unsigned and unencrypted, plain JSON both ways: the endpoint serves the merchant's own H5 checkout page, which has no access to the merchant private key. A nil error is not acceptance; see SubmitTradeNoResult.

func (*Client) VerifyWebhook

func (c *Client) VerifyWebhook(r *http.Request) ([]byte, error)

type Config

type Config struct {
	// Scheme and host of the platform API, https only. A path, query or fragment
	// is rejected: the SDK appends the endpoint path itself.
	BaseURL string

	AccessKey string
	// Ed25519 private key, base64. Both forms are accepted: the 32-byte seed that
	// libsodium and OpenSSL hand out, and Go's 64-byte seed-plus-public-key.
	MerchantPrivateKeyBase64 string

	// Names which platform key seals the request body; it travels in the envelope
	// so the gateway knows which private key opens it. Must name the key given in
	// PlatformBodyPublicKeyBase64.
	PlatformBodyKeyID string
	// Platform X25519 public key, base64, 32 bytes. Not the webhook key: that one
	// is Ed25519 and verifies signatures in the opposite direction.
	PlatformBodyPublicKeyBase64 string

	// Key id to platform Ed25519 public key, base64, 32 bytes each, for verifying
	// webhook signatures. The webhook names its key id, so this must hold every key
	// the platform may currently sign with; during a rotation that is two. Required
	// even when the merchant does not consume webhooks.
	PlatformWebhookPublicKeys map[string]string

	// Setting HTTPClient ignores Timeout, which only builds the default client.
	HTTPClient *http.Client
	Timeout    time.Duration // default 30s

	UserAgent        string
	AcceptLanguage   string
	MaxResponseBytes int64 // default 8 MiB
}

type CreatePaymentReq

type CreatePaymentReq struct {
	MerchantOrderNo string        `json:"merchantOrderNo"`
	Currency        string        `json:"currency"`
	Amount          string        `json:"amount"`
	Country         string        `json:"country,omitempty"`
	PaymentMethod   PaymentMethod `json:"paymentMethod"`
	ReturnUrl       string        `json:"returnUrl,omitempty"`
	WebhookUrl      string        `json:"webhookUrl"`
	Attach          string        `json:"attach,omitempty"`
}
Example (Pen)

These examples only build requests; they do not send payments. Replace all fictional identity and account details before using a real client.

methods := []PaymentMethod{
	{
		Code: MethodCodeBankTransfer,
		BankTransfer: &PaymentBankTransferExtra{
			CustomerName: "Test Payer", CustomerPhone: "912345678", CustomerEmail: "payer@example.test",
			DocumentType: "DNI", DocumentNumber: "12345678",
		},
	},
	{
		Code: MethodCodeEWallet,
		EWallet: &PaymentEWalletExtra{
			CustomerName: "Test Payer", CustomerPhone: "912345678", CustomerEmail: "payer@example.test",
			DocumentType: "DNI", DocumentNumber: "12345678",
		},
	},
	{
		Code: MethodCodeCash,
		Cash: &PaymentCustomerDocumentContactExtra{
			CustomerName: "Test Payer", CustomerPhone: "912345678", CustomerEmail: "payer@example.test",
			DocumentType: "DNI", DocumentNumber: "12345678",
		},
	},
}
for i, method := range methods {
	req := CreatePaymentReq{
		MerchantOrderNo: fmt.Sprintf("pen-payment-example-%d", i+1),
		Currency:        CurrencyPEN, Country: "PE", Amount: "10.25",
		PaymentMethod: method,
		ReturnUrl:     "https://merchant.example.test/return",
		WebhookUrl:    "https://merchant.example.test/webhook/payment",
	}
	body, err := json.Marshal(req)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(body))
}
// After creation, redirect the payer to order.Action.Url.
// Opening or returning from that page does not confirm payment.
Output:
{"merchantOrderNo":"pen-payment-example-1","currency":"PEN","amount":"10.25","country":"PE","paymentMethod":{"code":"BANK_TRANSFER","bankTransfer":{"customerName":"Test Payer","customerPhone":"912345678","customerEmail":"payer@example.test","documentType":"DNI","documentNumber":"12345678"}},"returnUrl":"https://merchant.example.test/return","webhookUrl":"https://merchant.example.test/webhook/payment"}
{"merchantOrderNo":"pen-payment-example-2","currency":"PEN","amount":"10.25","country":"PE","paymentMethod":{"code":"E_WALLET","eWallet":{"customerName":"Test Payer","customerPhone":"912345678","customerEmail":"payer@example.test","documentType":"DNI","documentNumber":"12345678"}},"returnUrl":"https://merchant.example.test/return","webhookUrl":"https://merchant.example.test/webhook/payment"}
{"merchantOrderNo":"pen-payment-example-3","currency":"PEN","amount":"10.25","country":"PE","paymentMethod":{"code":"CASH","cash":{"documentType":"DNI","documentNumber":"12345678","customerName":"Test Payer","customerPhone":"912345678","customerEmail":"payer@example.test"}},"returnUrl":"https://merchant.example.test/return","webhookUrl":"https://merchant.example.test/webhook/payment"}

type CreatePayoutReq

type CreatePayoutReq struct {
	MerchantOrderNo string       `json:"merchantOrderNo"`
	Currency        string       `json:"currency"`
	Amount          string       `json:"amount"`
	Country         string       `json:"country,omitempty"`
	PayoutMethod    PayoutMethod `json:"payoutMethod"`
	WebhookUrl      string       `json:"webhookUrl"`
	Attach          string       `json:"attach,omitempty"`
}
Example (Pen)
methods := []PayoutMethod{
	{
		Code: MethodCodeBankTransfer,
		BankTransfer: &PayoutBankTransferExtra{
			DocumentType: "DNI", DocumentNumber: "12345678",
			CustomerPhone: "912345678", CustomerEmail: "recipient@example.test",
			AccountName: "Test Recipient", AccountNo: "00123456789",
			AccountType: "SAVINGS", BankCode: "002", CciNo: "00212345678901234567",
		},
	},
	{
		Code: MethodCodeEWallet,
		EWallet: &PayoutEWalletExtra{
			DocumentType: "DNI", DocumentNumber: "12345678",
			CustomerPhone: "912345678", CustomerEmail: "recipient@example.test",
			AccountName: "Test Recipient", AccountNo: "912345678", BankCode: "026", // Yape
		},
	},
	{
		Code: MethodCodeEWallet,
		EWallet: &PayoutEWalletExtra{
			DocumentType: "DNI", DocumentNumber: "12345678",
			CustomerPhone: "912345678", CustomerEmail: "recipient@example.test",
			AccountName: "Test Recipient", AccountNo: "912345678", BankCode: "025", // Plin
		},
	},
}
for i, method := range methods {
	req := CreatePayoutReq{
		MerchantOrderNo: fmt.Sprintf("pen-payout-example-%d", i+1),
		Currency:        CurrencyPEN, Country: "PE", Amount: "10.25",
		PayoutMethod: method,
		WebhookUrl:   "https://merchant.example.test/webhook/payout",
	}
	body, err := json.Marshal(req)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(body))
}
// Account numbers and the bank CCI remain strings to preserve leading zeros.
// Wallet accountNo identifies the recipient; customerPhone is contact information.
Output:
{"merchantOrderNo":"pen-payout-example-1","currency":"PEN","amount":"10.25","country":"PE","payoutMethod":{"code":"BANK_TRANSFER","bankTransfer":{"documentType":"DNI","documentNumber":"12345678","customerPhone":"912345678","customerEmail":"recipient@example.test","accountName":"Test Recipient","accountNo":"00123456789","accountType":"SAVINGS","bankCode":"002","cciNo":"00212345678901234567"}},"webhookUrl":"https://merchant.example.test/webhook/payout"}
{"merchantOrderNo":"pen-payout-example-2","currency":"PEN","amount":"10.25","country":"PE","payoutMethod":{"code":"E_WALLET","eWallet":{"documentType":"DNI","documentNumber":"12345678","customerPhone":"912345678","customerEmail":"recipient@example.test","accountName":"Test Recipient","accountNo":"912345678","bankCode":"026"}},"webhookUrl":"https://merchant.example.test/webhook/payout"}
{"merchantOrderNo":"pen-payout-example-3","currency":"PEN","amount":"10.25","country":"PE","payoutMethod":{"code":"E_WALLET","eWallet":{"documentType":"DNI","documentNumber":"12345678","customerPhone":"912345678","customerEmail":"recipient@example.test","accountName":"Test Recipient","accountNo":"912345678","bankCode":"025"}},"webhookUrl":"https://merchant.example.test/webhook/payout"}

func (CreatePayoutReq) MarshalJSON added in v0.3.0

func (r CreatePayoutReq) MarshalJSON() ([]byte, error)

type Option

type Option func(*Client)

func WithClock

func WithClock(now func() time.Time) Option

WithClock overrides the clock used for signature timestamps.

type OrderAction

type OrderAction struct {
	Url string `json:"url,omitempty"`
	// Payment content for merchant-built checkout. See the corresponding currency
	// and payment method page for the format.
	PayContent string `json:"payContent,omitempty"`
	QrCode     string `json:"qrCode,omitempty"`
}

type PaymentAccountContactExtra

type PaymentAccountContactExtra struct {
	AccountName string `json:"accountName,omitempty"`
	Email       string `json:"email,omitempty"`
	Mobile      string `json:"mobile,omitempty"`
}

type PaymentArsDocumentExtra

type PaymentArsDocumentExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	FirstName      string `json:"firstName,omitempty"`
	LastName       string `json:"lastName,omitempty"`
	Email          string `json:"email,omitempty"`
	Phone          string `json:"phone,omitempty"` // Required for ARS CVU.
}

type PaymentArsQrisExtra

type PaymentArsQrisExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	FirstName      string `json:"firstName,omitempty"`
	LastName       string `json:"lastName,omitempty"`
	Email          string `json:"email,omitempty"`
	Phone          string `json:"phone,omitempty"`
}

type PaymentBankAccountContactExtra

type PaymentBankAccountContactExtra struct {
	AccountName string `json:"accountName,omitempty"`
	Email       string `json:"email,omitempty"`
	Mobile      string `json:"mobile,omitempty"`
	BankCode    string `json:"bankCode,omitempty"`
	AccountNo   string `json:"accountNo,omitempty"`
}

type PaymentBankTransferExtra

type PaymentBankTransferExtra struct {
	CustomerId     string `json:"customerId,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	FirstName      string `json:"firstName,omitempty"`
	LastName       string `json:"lastName,omitempty"`
	Email          string `json:"email,omitempty"`
}

type PaymentBdWalletExtra

type PaymentBdWalletExtra struct {
	PayType     string `json:"payType,omitempty"`
	AccountName string `json:"accountName,omitempty"`
	Email       string `json:"email,omitempty"`
	Mobile      string `json:"mobile,omitempty"`
}

type PaymentCheckout

type PaymentCheckout struct {
	OrderNo     string         `json:"orderNo"`
	OrderStatus int64          `json:"orderStatus"`
	Status      string         `json:"status"`
	Amount      string         `json:"amount"`
	Currency    string         `json:"currency"`
	PayMethod   string         `json:"payMethod"`
	Attach      string         `json:"attach"`
	ReturnUrl   string         `json:"returnUrl,omitempty"`
	Params      CheckoutParams `json:"params"`
	CreateTime  int64          `json:"createTime"`
	UpdateTime  int64          `json:"updateTime"`
}

type PaymentCustomerDocumentContactExtra

type PaymentCustomerDocumentContactExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
}

type PaymentCustomerDocumentEmailExtra

type PaymentCustomerDocumentEmailExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
}

type PaymentEWalletExtra

type PaymentEWalletExtra struct {
	CustomerId     string `json:"customerId,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
}

type PaymentMethod

type PaymentMethod struct {
	Code            string                               `json:"code"`
	Pix             *PaymentPixExtra                     `json:"pix,omitempty"`
	PagoFacil       *PaymentArsDocumentExtra             `json:"pagoFacil,omitempty"`
	Rapipago        *PaymentArsDocumentExtra             `json:"rapipago,omitempty"`
	BankTransfer    *PaymentBankTransferExtra            `json:"bankTransfer,omitempty"`
	Cvu             *PaymentArsDocumentExtra             `json:"cvu,omitempty"`
	Qris            *PaymentArsQrisExtra                 `json:"qris,omitempty"`
	Spei            *PaymentSpeiExtra                    `json:"spei,omitempty"`
	Cash            *PaymentCustomerDocumentContactExtra `json:"cash,omitempty"`
	Pse             *PaymentPseExtra                     `json:"pse,omitempty"`
	Nequi           *PaymentNequiExtra                   `json:"nequi,omitempty"`
	Transfiya       *PaymentCustomerDocumentContactExtra `json:"transfiya,omitempty"`
	Breb            *PaymentCustomerDocumentContactExtra `json:"breb,omitempty"`
	Webpay          *PaymentCustomerDocumentEmailExtra   `json:"webpay,omitempty"`
	Khipu           *PaymentCustomerDocumentEmailExtra   `json:"khipu,omitempty"`
	Mach            *PaymentCustomerDocumentEmailExtra   `json:"mach,omitempty"`
	Pago46          *PaymentCustomerDocumentEmailExtra   `json:"pago46,omitempty"`
	ServiFacil      *PaymentCustomerDocumentEmailExtra   `json:"serviFacil,omitempty"`
	EWallet         *PaymentEWalletExtra                 `json:"eWallet,omitempty"`
	CashApp         *PaymentUsCustomerExtra              `json:"cashApp,omitempty"`
	CreditCard      *PaymentUsCustomerExtra              `json:"creditCard,omitempty"`
	ApplePay        *PaymentUsCustomerExtra              `json:"applePay,omitempty"`
	GooglePay       *PaymentUsCustomerExtra              `json:"googlePay,omitempty"`
	Neteller        *PaymentUsCustomerExtra              `json:"neteller,omitempty"`
	Skrill          *PaymentUsCustomerExtra              `json:"skrill,omitempty"`
	UsdtTrc20       *PaymentUsdtExtra                    `json:"usdtTrc20,omitempty"`
	UsdtErc20       *PaymentUsdtExtra                    `json:"usdtErc20,omitempty"`
	UsdtBep20       *PaymentUsdtExtra                    `json:"usdtBep20,omitempty"`
	BdBkash         *PaymentBdWalletExtra                `json:"bdBkash,omitempty"`
	BdNagad         *PaymentBdWalletExtra                `json:"bdNagad,omitempty"`
	IdVa            *PaymentBankAccountContactExtra      `json:"idVa,omitempty"`
	IdQris          *PaymentBankAccountContactExtra      `json:"idQris,omitempty"`
	IdDana          *PaymentBankAccountContactExtra      `json:"idDana,omitempty"`
	IdOvo           *PaymentBankAccountContactExtra      `json:"idOvo,omitempty"`
	IdGopay         *PaymentBankAccountContactExtra      `json:"idGopay,omitempty"`
	IdLinkaja       *PaymentBankAccountContactExtra      `json:"idLinkaja,omitempty"`
	IdShopeepay     *PaymentBankAccountContactExtra      `json:"idShopeepay,omitempty"`
	PhGcash         *PaymentAccountContactExtra          `json:"phGcash,omitempty"`
	PhMaya          *PaymentAccountContactExtra          `json:"phMaya,omitempty"`
	PhGrab          *PaymentAccountContactExtra          `json:"phGrab,omitempty"`
	PhQris          *PaymentAccountContactExtra          `json:"phQris,omitempty"`
	PhGcashQr       *PaymentAccountContactExtra          `json:"phGcashQr,omitempty"`
	PhMayaQr        *PaymentAccountContactExtra          `json:"phMayaQr,omitempty"`
	PhNativeGcash   *PaymentAccountContactExtra          `json:"phNativeGcash,omitempty"`
	PkJazzcash      *PaymentPkWalletExtra                `json:"pkJazzcash,omitempty"`
	PkEasypaisa     *PaymentPkWalletExtra                `json:"pkEasypaisa,omitempty"`
	PkJazzcashQrph  *PaymentPkWalletExtra                `json:"pkJazzcashQrph,omitempty"`
	PkEasypaisaQrph *PaymentPkWalletExtra                `json:"pkEasypaisaQrph,omitempty"`
	ThBankCard      *PaymentBankAccountContactExtra      `json:"thBankCard,omitempty"`
	ThTruemoney     *PaymentBankAccountContactExtra      `json:"thTruemoney,omitempty"`
	ThPromptpay     *PaymentBankAccountContactExtra      `json:"thPromptpay,omitempty"`
	InUpi           *PaymentAccountContactExtra          `json:"inUpi,omitempty"`
	// contains filtered or unexported fields
}

PaymentMethod holds strongly-typed fields for every current payment method branch. For a method not yet in a release, wire it at runtime via SetExtra("xxx", payload).

func (PaymentMethod) MarshalJSON

func (m PaymentMethod) MarshalJSON() ([]byte, error)

func (*PaymentMethod) SetExtra

func (m *PaymentMethod) SetExtra(field string, value any) error

SetExtra injects the payload for an unlisted method, overriding a same-named typed field. It returns ErrInvalidExtraField when field is empty or "code".

type PaymentNequiExtra

type PaymentNequiExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	AccountNo      string `json:"accountNo,omitempty"`
}

type PaymentOrder

type PaymentOrder struct {
	OrderNo         string          `json:"orderNo"`
	MerchantOrderNo string          `json:"merchantOrderNo"`
	Status          string          `json:"status"`
	Currency        string          `json:"currency"`
	Amount          string          `json:"amount"`
	PaidAmount      string          `json:"paidAmount"`
	Payer           *PaymentPayer   `json:"payer,omitempty"`
	Country         string          `json:"country,omitempty"`
	PaymentMethod   string          `json:"paymentMethod"`
	Action          OrderAction     `json:"action"`
	Attach          string          `json:"attach,omitempty"`
	Failure         *WebhookFailure `json:"failure,omitempty"`
	CreatedAt       int64           `json:"createdAt"`
	UpdatedAt       int64           `json:"updatedAt"`
}

type PaymentPayer added in v0.5.0

type PaymentPayer struct {
	Name           string `json:"name,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
}

PaymentPayer is reported by the channel, not copied from the create request. It is available in authenticated payment queries and payment webhooks.

type PaymentPixExtra

type PaymentPixExtra struct {
	PayerCPF  string `json:"payerCPF,omitempty"`
	PayerName string `json:"payerName,omitempty"`
	CpfVerify *bool  `json:"cpfVerify,omitempty"`
}

type PaymentPkWalletExtra

type PaymentPkWalletExtra struct {
	AccountNo   string `json:"accountNo,omitempty"`
	AccountName string `json:"accountName,omitempty"`
	Email       string `json:"email,omitempty"`
	Mobile      string `json:"mobile,omitempty"`
	AutoFill    string `json:"autoFill,omitempty"`
	Direct      string `json:"direct,omitempty"`
}

type PaymentPseExtra

type PaymentPseExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	BankCode       string `json:"bankCode,omitempty"`
}

type PaymentSpeiExtra

type PaymentSpeiExtra struct {
	AllowMultiplePayments bool   `json:"allowMultiplePayments,omitempty"`
	MinAmount             string `json:"minAmount,omitempty"`
	MaxAmount             string `json:"maxAmount,omitempty"`
}

PaymentSpeiExtra holds the MXN SPEI pay-in extra fields.

The amount mode is set by MinAmount / MaxAmount, orthogonal to AllowMultiplePayments:

  • both 0: fixed amount; the settled amount equals CreatePaymentReq.Amount.
  • both > 0: range amount; the settled amount is reported in PaidAmount.

AllowMultiplePayments controls whether one pay-in entry accepts multiple valid payments (default false).

type PaymentUsCustomerExtra

type PaymentUsCustomerExtra struct {
	Name      string `json:"name,omitempty"`
	Phone     string `json:"phone,omitempty"`
	Email     string `json:"email,omitempty"`
	IpAddress string `json:"ipAddress,omitempty"`
}

type PaymentUsdtExtra

type PaymentUsdtExtra struct {
	CustomerId string `json:"customerId,omitempty"`
}

type PaymentWebhook

type PaymentWebhook struct {
	EventID         string          `json:"eventId"`
	OrderType       string          `json:"orderType"`
	OrderNo         string          `json:"orderNo"`
	MerchantOrderNo string          `json:"merchantOrderNo"`
	Status          string          `json:"status"`
	Currency        string          `json:"currency"`
	Amount          string          `json:"amount"`
	PaidAmount      string          `json:"paidAmount,omitempty"`
	Payer           *PaymentPayer   `json:"payer,omitempty"`
	ChannelTradeNo  string          `json:"channelTradeNo,omitempty"`
	Attach          string          `json:"attach,omitempty"`
	Failure         *WebhookFailure `json:"failure,omitempty"`
}

type PayoutAccountContactExtra

type PayoutAccountContactExtra struct {
	AccountNo   string `json:"accountNo,omitempty"`
	AccountName string `json:"accountName,omitempty"`
	Email       string `json:"email,omitempty"`
	Mobile      string `json:"mobile,omitempty"`
}

type PayoutBankAccountContactExtra

type PayoutBankAccountContactExtra struct {
	AccountNo   string `json:"accountNo,omitempty"`
	BankCode    string `json:"bankCode,omitempty"`
	AccountName string `json:"accountName,omitempty"`
	Email       string `json:"email,omitempty"`
	Mobile      string `json:"mobile,omitempty"`
}

type PayoutBankTransferExtra

type PayoutBankTransferExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	FirstName      string `json:"firstName,omitempty"`
	LastName       string `json:"lastName,omitempty"`
	Name           string `json:"name,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
	Phone          string `json:"phone,omitempty"`
	Email          string `json:"email,omitempty"`
	Address        string `json:"address,omitempty"`
	AccountName    string `json:"accountName,omitempty"`
	AccountNo      string `json:"accountNo,omitempty"`
	AccountType    string `json:"accountType,omitempty"`
	BankCode       string `json:"bankCode,omitempty"`
	BankName       string `json:"bankName,omitempty"`
	CciNo          string `json:"cciNo,omitempty"`
}

type PayoutCashAppExtra

type PayoutCashAppExtra struct {
	Name               string `json:"name,omitempty"`
	Phone              string `json:"phone,omitempty"`
	Email              string `json:"email,omitempty"`
	AccountNo          string `json:"accountNo,omitempty"`
	FirstName          string `json:"firstName,omitempty"`
	LastName           string `json:"lastName,omitempty"`
	DateOfBirth        string `json:"dateOfBirth,omitempty"`
	CountryOfResidence string `json:"countryOfResidence,omitempty"`
	StateOfResidence   string `json:"stateOfResidence,omitempty"`
	CardCity           string `json:"cardCity,omitempty"`
	CardStreet         string `json:"cardStreet,omitempty"`
	CardPostCode       string `json:"cardPostCode,omitempty"`
}

PayoutCashAppExtra is shared by USD Cash App, PayPal and Chime payouts. cardCity, cardStreet and cardPostCode describe the recipient address, not a card.

type PayoutColombiaBankExtra

type PayoutColombiaBankExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
	AccountNo      string `json:"accountNo,omitempty"`
	BankName       string `json:"bankName,omitempty"`
	BankCode       string `json:"bankCode,omitempty"`
	AccountType    string `json:"accountType,omitempty"`
}

type PayoutEWalletExtra

type PayoutEWalletExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
	AccountName    string `json:"accountName,omitempty"`
	AccountNo      string `json:"accountNo,omitempty"`
	BankCode       string `json:"bankCode,omitempty"`
}

type PayoutInIfscExtra

type PayoutInIfscExtra struct {
	Account string `json:"account,omitempty"`
	Ifsc    string `json:"ifsc,omitempty"`
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
	Mobile  string `json:"mobile,omitempty"`
}

type PayoutInUpiExtra

type PayoutInUpiExtra struct {
	Account string `json:"account,omitempty"`
	Name    string `json:"name,omitempty"`
	Email   string `json:"email,omitempty"`
	Mobile  string `json:"mobile,omitempty"`
}

type PayoutMethod

type PayoutMethod struct {
	Code           string                         `json:"code"`
	Pix            *PayoutPixExtra                `json:"pix,omitempty"`
	BankTransfer   *PayoutBankTransferExtra       `json:"bankTransfer,omitempty"`
	Breb           *PayoutColombiaBankExtra       `json:"breb,omitempty"`
	BankCard       *PayoutColombiaBankExtra       `json:"bankCard,omitempty"`
	Transfiya      *PayoutTransfiyaExtra          `json:"transfiya,omitempty"`
	Papara         *PayoutPaparaExtra             `json:"papara,omitempty"`
	CashApp        *PayoutCashAppExtra            `json:"cashApp,omitempty"`
	PayPal         *PayoutCashAppExtra            `json:"paypal,omitempty"`
	Chime          *PayoutCashAppExtra            `json:"chime,omitempty"`
	UsdtTrc20      *PayoutUsdtExtra               `json:"usdtTrc20,omitempty"`
	UsdtErc20      *PayoutUsdtExtra               `json:"usdtErc20,omitempty"`
	UsdtBep20      *PayoutUsdtExtra               `json:"usdtBep20,omitempty"`
	P2P            *PayoutRubBankExtra            `json:"p2p,omitempty"`
	Sbp            *PayoutRubBankExtra            `json:"sbp,omitempty"`
	BdBkash        *PayoutAccountContactExtra     `json:"bdBkash,omitempty"`
	BdNagad        *PayoutAccountContactExtra     `json:"bdNagad,omitempty"`
	IdBankTransfer *PayoutBankAccountContactExtra `json:"idBankTransfer,omitempty"`
	IdDana         *PayoutBankAccountContactExtra `json:"idDana,omitempty"`
	IdOvo          *PayoutBankAccountContactExtra `json:"idOvo,omitempty"`
	IdGopay        *PayoutBankAccountContactExtra `json:"idGopay,omitempty"`
	IdLinkaja      *PayoutBankAccountContactExtra `json:"idLinkaja,omitempty"`
	IdShopeepay    *PayoutBankAccountContactExtra `json:"idShopeepay,omitempty"`
	PhGcash        *PayoutBankAccountContactExtra `json:"phGcash,omitempty"`
	PhMaya         *PayoutBankAccountContactExtra `json:"phMaya,omitempty"`
	PhDfWallet     *PayoutBankAccountContactExtra `json:"phDfWallet,omitempty"`
	PhDfBank       *PayoutBankAccountContactExtra `json:"phDfBank,omitempty"`
	EWallet        *PayoutEWalletExtra            `json:"eWallet,omitempty"`
	PkJazzcash     *PayoutPkDfExtra               `json:"pkJazzcash,omitempty"`
	PkEasypaisa    *PayoutPkDfExtra               `json:"pkEasypaisa,omitempty"`
	PkBank         *PayoutPkDfExtra               `json:"pkBank,omitempty"`
	ThBankTransfer *PayoutBankAccountContactExtra `json:"thBankTransfer,omitempty"`
	InIfsc         *PayoutInIfscExtra             `json:"inIfsc,omitempty"`
	InUpi          *PayoutInUpiExtra              `json:"inUpi,omitempty"`
	// contains filtered or unexported fields
}

PayoutMethod holds strongly-typed fields for every current payout branch; like PaymentMethod, use SetExtra for an unlisted method.

func (PayoutMethod) MarshalJSON

func (m PayoutMethod) MarshalJSON() ([]byte, error)

func (*PayoutMethod) SetExtra

func (m *PayoutMethod) SetExtra(field string, value any) error

type PayoutOrder

type PayoutOrder struct {
	RefundNo        string          `json:"refundNo,omitempty"`
	RefundAmount    string          `json:"refundAmount,omitempty"`
	RefundTime      int64           `json:"refundTime,omitempty"`
	OrderNo         string          `json:"orderNo"`
	MerchantOrderNo string          `json:"merchantOrderNo"`
	Status          string          `json:"status"`
	Currency        string          `json:"currency"`
	Amount          string          `json:"amount"`
	Country         string          `json:"country,omitempty"`
	PayoutMethod    string          `json:"payoutMethod"`
	Action          OrderAction     `json:"action"`
	Attach          string          `json:"attach,omitempty"`
	Failure         *WebhookFailure `json:"failure,omitempty"`
	CreatedAt       int64           `json:"createdAt"`
	UpdatedAt       int64           `json:"updatedAt"`
}

type PayoutPaparaExtra

type PayoutPaparaExtra struct {
	AccountName string `json:"accountName,omitempty"`
	AccountNo   string `json:"accountNo,omitempty"`
}

type PayoutPixExtra

type PayoutPixExtra struct {
	KeyType     string `json:"keyType,omitempty"`
	Key         string `json:"key,omitempty"`
	Document    string `json:"document,omitempty"`
	AccountName string `json:"accountName,omitempty"`
	CpfVerify   *bool  `json:"cpfVerify,omitempty"`
	AccountType string `json:"accountType,omitempty"`
	BankBranch  string `json:"bankBranch,omitempty"`
}

type PayoutPkDfExtra

type PayoutPkDfExtra struct {
	AccountNo   string `json:"accountNo,omitempty"`
	Cnic        string `json:"cnic,omitempty"`
	BankCode    string `json:"bankCode,omitempty"`
	AccountName string `json:"accountName,omitempty"`
	Email       string `json:"email,omitempty"`
	Mobile      string `json:"mobile,omitempty"`
}

type PayoutReceipt

type PayoutReceipt struct {
	OrderNo            string          `json:"orderNo"`
	Amount             string          `json:"amount"`
	Currency           string          `json:"currency"`
	Timestamp          int64           `json:"timestamp"`
	ChannelTradeNo     string          `json:"channelTradeNo,omitempty"`
	SourceAccount      *ReceiptAccount `json:"sourceAccount,omitempty"`
	DestinationAccount *ReceiptAccount `json:"destinationAccount,omitempty"`
	Url                string          `json:"url,omitempty"`
}

type PayoutRubBankExtra

type PayoutRubBankExtra struct {
	Name      string `json:"name,omitempty"`
	Phone     string `json:"phone,omitempty"`
	Email     string `json:"email,omitempty"`
	BankCode  string `json:"bankCode,omitempty"`
	AccountNo string `json:"accountNo,omitempty"`
}

type PayoutTransfiyaExtra

type PayoutTransfiyaExtra struct {
	DocumentType   string `json:"documentType,omitempty"`
	DocumentNumber string `json:"documentNumber,omitempty"`
	CustomerName   string `json:"customerName,omitempty"`
	CustomerPhone  string `json:"customerPhone,omitempty"`
	CustomerEmail  string `json:"customerEmail,omitempty"`
}

type PayoutUsdtExtra

type PayoutUsdtExtra struct {
	CryptoAddress string `json:"cryptoAddress,omitempty"`
	CustomerId    string `json:"customerId,omitempty"`
}

type PayoutWebhook

type PayoutWebhook struct {
	RefundNo        string          `json:"refundNo,omitempty"`
	RefundAmount    string          `json:"refundAmount,omitempty"`
	RefundTime      int64           `json:"refundTime,omitempty"`
	EventID         string          `json:"eventId"`
	OrderType       string          `json:"orderType"`
	OrderNo         string          `json:"orderNo"`
	MerchantOrderNo string          `json:"merchantOrderNo"`
	Status          string          `json:"status"`
	Currency        string          `json:"currency"`
	Amount          string          `json:"amount"`
	ChannelTradeNo  string          `json:"channelTradeNo,omitempty"`
	Attach          string          `json:"attach,omitempty"`
	Failure         *WebhookFailure `json:"failure,omitempty"`
}

type ReceiptAccount

type ReceiptAccount struct {
	Bank    *ReceiptBank `json:"bank,omitempty"`
	Name    string       `json:"name,omitempty"`
	TaxId   string       `json:"taxId,omitempty"`
	TaxType string       `json:"taxType,omitempty"`
	Key     string       `json:"key,omitempty"`
}

type ReceiptBank

type ReceiptBank struct {
	Ispb    string `json:"ispb,omitempty"`
	Name    string `json:"name,omitempty"`
	Branch  string `json:"branch,omitempty"`
	Account string `json:"account,omitempty"`
	Number  string `json:"number,omitempty"`
}

type RequestOption

type RequestOption func(*requestOptions)

func WithIdempotencyKey

func WithIdempotencyKey(key string) RequestOption

type ResponseError

type ResponseError struct {
	HTTPStatus int
	RawBody    []byte
}

ResponseError is returned when the server returned a non-envelope body (an HTML error page or plain-text 502 from the gateway or CDN); distinct from *APIError.

func (*ResponseError) Error

func (e *ResponseError) Error() string

type SubmitTradeNoResult

type SubmitTradeNoResult struct {
	Status int64 `json:"status"`
	// OrderStatus is the checkout-facing order status (CREATED / PENDING / …).
	OrderStatus string `json:"orderStatus,omitempty"`
	Message     string `json:"message,omitempty"`
}

SubmitTradeNoResult is the answer to SubmitPaymentTradeNo.

A nil error does not mean the platform accepted the call: the endpoint answers HTTP 200 with envelope code 200 even when it refuses, and the outcome is carried by Status: 1 accepted, 0 refused with Message giving the reason, so a nil error alone does not mean the submission was accepted.

func (*SubmitTradeNoResult) Ok

func (r *SubmitTradeNoResult) Ok() bool

Ok reports whether the platform accepted the submission.

type USDRate

type USDRate struct {
	UsdRate string `json:"usdRate"`
}

type WebhookFailure

type WebhookFailure struct {
	Code    int    `json:"code"`
	Msg     string `json:"msg"`
	Message string `json:"message"`
}

Directories

Path Synopsis
internal
merchantauth
Package merchantauth implements the merchant API request signing, body sealing and webhook verification primitives shared by the platform and the SDKs.
Package merchantauth implements the merchant API request signing, body sealing and webhook verification primitives shared by the platform and the SDKs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL