Documentation
¶
Overview ¶
Package sabi is the official Go client for the Sabi payment gateway.
It covers the whole client API -- payments and the hosted checkout, refunds and cancellations, payouts, transfers, balances and statements, fee quotes, callback configuration and partner merchant onboarding -- and verifies the callbacks Sabi posts to your application.
It depends on nothing outside the standard library.
Collecting a payment ¶
client := sabi.New("https://pay.example.et", os.Getenv("SABI_API_KEY"))
payment, err := client.CreatePayment(ctx, sabi.CreatePaymentParams{
Amount: "250.00",
Currency: "ETB",
ExternalReference: order.ID, // your own id; repeating it never charges twice
PayerName: order.CustomerName,
Narrative: "Order " + order.Number,
ReturnURL: "https://shop.example.et/orders/" + order.ID,
})
if err != nil {
return err
}
redirect(payment.CheckoutURL)
Hearing that it was paid ¶
http.Handle("/webhooks/sabi", sabi.WebhookHandler(os.Getenv("SABI_CALLBACK_SECRET"),
func(ctx context.Context, cb *sabi.Callback) error {
if cb.Event != sabi.EventCollectionSettled {
return nil // answer every event you do not handle with a 2xx
}
// A callback is a prompt: confirm with the API before acting.
p, err := client.GetPayment(ctx, cb.SabiReference)
if err != nil {
return err // a non-2xx answer makes Sabi retry
}
return markPaid(ctx, cb.DeliveryID, p)
}))
The handler refuses anything whose X-Sabi-Signature-V2 does not verify or is more than five minutes old, so a callback captured on the way cannot be replayed at you. Record DeliveryID and ignore a repeat: Sabi retries until your endpoint answers 2xx.
Errors ¶
Every failure the API reports is an *Error carrying the HTTP status, a stable Code to branch on and the RequestID to quote to Sabi. Requests that are safe to repeat -- every GET, and every call that carries an external reference -- are retried on rate limiting and on temporary server and network failures, with backoff; nothing else is.
Index ¶
- Constants
- Variables
- func ErrorCode(err error) string
- func FormatMinor(minor int64) string
- func IsNotFound(err error) bool
- func IsTemporary(err error) bool
- func Mode(apiKey string) string
- func OTPAttemptsLeft(err error) (left int, ok bool)
- func ParseMinor(amount string) (int64, error)
- func WebhookHandler(secret string, handle func(ctx context.Context, cb *Callback) error, ...) http.Handler
- type Account
- type AccountRule
- type Balance
- type BlocklistEntry
- type BulkPayoutItem
- type BulkPayoutParams
- type Callback
- type CallbackConfig
- type CallbackDelivery
- type CallbackDispute
- type CallbackTest
- type ChargeResult
- type CheckoutSession
- type Client
- func (c *Client) Account(ctx context.Context) (*Account, error)
- func (c *Client) Block(ctx context.Context, attribute, value, note string) (*BlocklistEntry, error)
- func (c *Client) Blocklist(ctx context.Context, limit, offset int) (*Page[BlocklistEntry], error)
- func (c *Client) CallbackURL(ctx context.Context) (*CallbackConfig, error)
- func (c *Client) CancelPayment(ctx context.Context, reference, reason string) (*Transaction, error)
- func (c *Client) Charge(ctx context.Context, reference, channel, account, payerName string) (*ChargeResult, error)
- func (c *Client) CheckoutSession(ctx context.Context, reference string) (*CheckoutSession, error)
- func (c *Client) CloseVirtualAccount(ctx context.Context, id string) (*VirtualAccount, error)
- func (c *Client) CreateBulkPayout(ctx context.Context, p BulkPayoutParams) (*PayoutBatch, error)
- func (c *Client) CreatePayment(ctx context.Context, p CreatePaymentParams) (*Transaction, error)
- func (c *Client) CreatePayout(ctx context.Context, p CreatePayoutParams) (*Transaction, error)
- func (c *Client) CreateSubaccount(ctx context.Context, p CreateSubaccountParams) (*Subaccount, error)
- func (c *Client) CreateTransfer(ctx context.Context, p CreateTransferParams) (*Transaction, error)
- func (c *Client) Currencies(ctx context.Context) ([]Currency, error)
- func (c *Client) DeactivateSubaccount(ctx context.Context, id string) (*Subaccount, error)
- func (c *Client) EmbedOrigins(ctx context.Context) (*EmbedOrigins, error)
- func (c *Client) GetMerchant(ctx context.Context, externalReference string) (*Merchant, error)
- func (c *Client) GetPayment(ctx context.Context, reference string) (*Transaction, error)
- func (c *Client) GetPayout(ctx context.Context, reference string) (*Transaction, error)
- func (c *Client) GetPayoutBatch(ctx context.Context, id string) (*PayoutBatch, error)
- func (c *Client) GetSubaccount(ctx context.Context, id string) (*Subaccount, error)
- func (c *Client) GetTransaction(ctx context.Context, reference string) (*Transaction, error)
- func (c *Client) ListAllRefunds(ctx context.Context, p ListParams) (*Page[Transaction], error)
- func (c *Client) ListCallbacks(ctx context.Context, status string, limit, offset int) (*Page[CallbackDelivery], error)
- func (c *Client) ListPayments(ctx context.Context, p ListParams) (*Page[Transaction], error)
- func (c *Client) ListPayouts(ctx context.Context, p ListParams) (*Page[Transaction], error)
- func (c *Client) ListRefunds(ctx context.Context, reference string) (*Refunds, error)
- func (c *Client) ListSubaccounts(ctx context.Context) ([]Subaccount, error)
- func (c *Client) ListTransactions(ctx context.Context, p ListParams) (*Page[Transaction], error)
- func (c *Client) ListVirtualAccounts(ctx context.Context, status string, limit, offset int) (*Page[VirtualAccount], error)
- func (c *Client) OpenVirtualAccount(ctx context.Context, p VirtualAccountParams) (*VirtualAccount, error)
- func (c *Client) PaymentMethods(ctx context.Context) ([]PaymentMethod, error)
- func (c *Client) QuoteFees(ctx context.Context, p FeeQuoteParams) (*Quote, error)
- func (c *Client) Rate(ctx context.Context, from, to, amount string) (*Rate, error)
- func (c *Client) RefundPayment(ctx context.Context, reference string, p RefundParams) (*Transaction, error)
- func (c *Client) RegisterMerchant(ctx context.Context, p RegisterMerchantParams) (*RegisteredMerchant, error)
- func (c *Client) ReplayCallback(ctx context.Context, deliveryID string) (*CallbackDelivery, error)
- func (c *Client) SetCallback(ctx context.Context, callbackURL string, events []string) (*CallbackConfig, error)
- func (c *Client) SetCallbackURL(ctx context.Context, callbackURL string) (*CallbackConfig, error)
- func (c *Client) SetEmbedOrigins(ctx context.Context, origins []string) (*EmbedOrigins, error)
- func (c *Client) SetSettlementAccount(ctx context.Context, externalReference string, p SettlementAccountParams) (*MerchantSettlement, error)
- func (c *Client) SetSettlementSchedule(ctx context.Context, externalReference string, p SettlementScheduleParams) (*MerchantSettlement, error)
- func (c *Client) SettlementAccount(ctx context.Context, externalReference string) (*MerchantSettlement, error)
- func (c *Client) SimulatorSettle(ctx context.Context, reference string) error
- func (c *Client) StartPaymentOTP(ctx context.Context, reference string, p StartPaymentOTPInput) (*PaymentOTP, error)
- func (c *Client) Statement(ctx context.Context, day time.Time) (*Statement, error)
- func (c *Client) TestCallback(ctx context.Context) (*CallbackTest, error)
- func (c *Client) TransactionEvents(ctx context.Context, reference string) (*Timeline, error)
- func (c *Client) Unblock(ctx context.Context, id string) error
- func (c *Client) UpdateMerchantOwner(ctx context.Context, externalReference string, p UpdateOwnerParams) (*Merchant, error)
- func (c *Client) VerifyPaymentOTP(ctx context.Context, reference, code string) (*PaymentOTPResult, error)
- func (c *Client) VirtualAccount(ctx context.Context, id string) (*VirtualAccount, error)
- func (c *Client) VirtualAccountDeposits(ctx context.Context, id string, limit, offset int) (*Page[VirtualAccountDeposit], error)
- type CreatePaymentParams
- type CreatePayoutParams
- type CreateSubaccountParams
- type CreateTransferParams
- type Currency
- type Customer
- type Customization
- type EmbedOrigins
- type Error
- type Fee
- type FeeQuoteParams
- type LineItem
- type ListParams
- type Merchant
- type MerchantCredentials
- type MerchantSettlement
- type MerchantSignIn
- type NetworkError
- type Option
- type Page
- type PaymentMethod
- type PaymentOTP
- type PaymentOTPCharge
- type PaymentOTPResult
- type PayoutBatch
- type PayoutBatchRow
- type Quote
- type Rate
- type RefundParams
- type Refunds
- type RegisterMerchantParams
- type RegisteredMerchant
- type SettlementAccount
- type SettlementAccountParams
- type SettlementSchedule
- type SettlementScheduleParams
- type StartPaymentOTPInput
- type Statement
- type StatementLine
- type Subaccount
- type SubaccountSplit
- type Timeline
- type TimelineEvent
- type Transaction
- type UpdateOwnerParams
- type VerifyOptions
- type VirtualAccount
- type VirtualAccountDeposit
- type VirtualAccountParams
Constants ¶
const ( CodeInvalidAPIKey = "INVALID_API_KEY" CodeLiveModeNotActivated = "LIVE_MODE_NOT_ACTIVATED" CodeClientSuspended = "CLIENT_SUSPENDED" CodeValidationFailed = "VALIDATION_FAILED" CodeInsufficientBalance = "INSUFFICIENT_BALANCE" CodeNoSuchPayment = "NO_SUCH_PAYMENT" CodeAlreadyPaid = "ALREADY_PAID" CodeNotRefundable = "NOT_REFUNDABLE" CodeRefundExceedsPayment = "REFUND_EXCEEDS_PAYMENT" CodeNothingToRefund = "NOTHING_TO_REFUND" CodePaymentInProgress = "PAYMENT_IN_PROGRESS" CodeNotCancellable = "NOT_CANCELLABLE" CodeRateLimited = "RATE_LIMITED" CodeNotAPartner = "NOT_A_PARTNER" CodeMerchantNotFound = "MERCHANT_NOT_FOUND" CodePhoneInUse = "PHONE_IN_USE" CodeEmailInUse = "EMAIL_IN_USE" CodePrivateCallbackURL = "PRIVATE_CALLBACK_URL" CodeInsecureCallbackURL = "INSECURE_CALLBACK_URL" CodeDeliveryNotReplayable = "DELIVERY_NOT_REPLAYABLE" // Paying from a wallet on a one-time code (StartPaymentOTP and // VerifyPaymentOTP). CodeOTPNotAvailable = "OTP_NOT_AVAILABLE" CodeMethodNotOffered = "METHOD_NOT_OFFERED" CodeInvalidAccount = "INVALID_ACCOUNT" CodeNotPayable = "NOT_PAYABLE" CodeExpired = "EXPIRED" CodeTooManyCodes = "TOO_MANY_CODES" CodeOTPNotRequested = "OTP_NOT_REQUESTED" CodeOTPExpired = "OTP_EXPIRED" CodeOTPInvalid = "OTP_INVALID" CodeOTPLocked = "OTP_LOCKED" CodeTooManyAttempts = "TOO_MANY_ATTEMPTS" )
Error codes an integration commonly branches on. The full list is in the API reference; any code not listed here is still returned in Error.Code.
const ( StatusPending = "pending" StatusSettled = "settled" StatusFailed = "failed" StatusExpired = "expired" StatusCancelled = "cancelled" )
Transaction statuses.
const ( TypePayment = "payment" TypeEscrowFunding = "escrow_funding" TypeBidBond = "bid_bond" TypeDeposit = "deposit" TypeWithdrawal = "withdrawal" TypeEscrowRelease = "escrow_release" TypeRefund = "refund" TypeTransfer = "transfer" )
Transaction types.
const ( EventCollectionSettled = "collection.settled" EventCollectionFailed = "collection.failed" EventPayoutPaid = "payout.paid" EventPayoutFailed = "payout.failed" EventTransferReceived = "transfer.received" // EventPing is sent by TestCallback and nothing else. EventPing = "ping" // Optional events, sent only when chosen with SetCallback. Choosing the // refund events reports refunds by them instead of by payout.paid and // payout.failed. EventPaymentCancelled = "payment.cancelled" EventPaymentExpired = "payment.expired" EventRefundSucceeded = "refund.succeeded" EventRefundFailed = "refund.failed" EventDisputeOpened = "dispute.opened" EventDisputeWon = "dispute.won" EventDisputeLost = "dispute.lost" EventDisputeAccepted = "dispute.accepted" )
Callback events.
const ( HeaderSignatureV2 = "X-Sabi-Signature-V2" HeaderTimestamp = "X-Sabi-Timestamp" HeaderDelivery = "X-Sabi-Delivery" HeaderEvent = "X-Sabi-Event" // HeaderSignature is the older signature over the body alone. It can be // replayed, so VerifyCallback ignores it unless told otherwise. HeaderSignature = "X-Sabi-Signature" )
Callback headers.
const DefaultTolerance = 5 * time.Minute
DefaultTolerance is how old a callback may be before it is refused.
const Version = "1.3.0"
Version is this client's version, sent in the User-Agent.
Variables ¶
var ( ErrMissingSignature = errors.New("sabi: the callback is not signed") ErrBadSignature = errors.New("sabi: the callback signature does not match") ErrStaleCallback = errors.New("sabi: the callback is too old or from the future") )
Errors VerifyCallback returns.
var ErrInvalidAmount = errors.New("sabi: not a decimal amount with at most two decimal places")
ErrInvalidAmount is a decimal string that is not an amount of money.
Functions ¶
func FormatMinor ¶
FormatMinor turns minor units (125050) into the decimal string the API takes ("1250.50").
func IsNotFound ¶
IsNotFound reports whether Sabi answered 404: no such object, or another client's, which Sabi reports the same way.
func IsTemporary ¶
IsTemporary reports whether the same request may succeed later: a network failure, rate limiting, or a server-side failure. Validation errors, conflicts and authentication failures are not temporary.
func Mode ¶
Mode is what the key's prefix says about it: "live" for real money, "sandbox" for a merchant's test account. GET /v1/account says the same with authority; this is for checking configuration before any call.
func OTPAttemptsLeft ¶ added in v1.3.0
OTPAttemptsLeft is how many more codes may be tried after an OTP_INVALID answer from VerifyPaymentOTP. ok is false for any other error.
func ParseMinor ¶
ParseMinor turns a decimal amount such as "1250.50" into minor units (125050), exactly, with no floating point anywhere. Birr has two decimal places.
func WebhookHandler ¶
func WebhookHandler(secret string, handle func(ctx context.Context, cb *Callback) error, opts ...VerifyOptions) http.Handler
WebhookHandler is an http.Handler for your callback URL. It verifies each callback and passes it to handle; an error from handle answers 500, which makes Sabi retry the delivery later. A callback that fails verification is answered 401 and never reaches handle.
Types ¶
type Account ¶
type Account struct {
Client string `json:"client"`
Name string `json:"name"`
// Mode is "live" or "test".
Mode string `json:"mode"`
Status string `json:"status"`
Balances []Balance `json:"accounts"`
}
Account is who an API key belongs to and what it holds.
type AccountRule ¶
type AccountRule struct {
MinDigits int `json:"min_digits"`
MaxDigits int `json:"max_digits"`
Prefixes []string `json:"prefixes,omitempty"`
Luhn bool `json:"luhn,omitempty"`
Example string `json:"example"`
}
AccountRule is what an account number on a channel looks like.
type Balance ¶
type Balance struct {
// Purpose is "settlement" (money collected for you) or "fee_income".
Purpose string `json:"purpose"`
Currency string `json:"currency"`
Balance string `json:"balance"`
// Held is what open disputes hold back and Available what can be paid
// out now; settlement accounts only.
Held string `json:"held,omitempty"`
Available string `json:"available,omitempty"`
}
Balance is one of a client's accounts.
type BlocklistEntry ¶
type BlocklistEntry struct {
ID string `json:"id"`
// Attribute is "account", "ip" or "email".
Attribute string `json:"attribute"`
Value string `json:"value"`
Note string `json:"note,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
BlocklistEntry is a value refused on your traffic. Value is shown masked for an account; Sabi keeps it only as a keyed hash.
type BulkPayoutItem ¶
type BulkPayoutItem struct {
ExternalReference string `json:"external_reference"`
Amount string `json:"amount"`
BeneficiaryBankCode string `json:"beneficiary_bank_code"`
BeneficiaryAccount string `json:"beneficiary_account"`
BeneficiaryName string `json:"beneficiary_name"`
Narrative string `json:"narrative,omitempty"`
}
BulkPayoutItem is one payout of a batch.
type BulkPayoutParams ¶
type BulkPayoutParams struct {
Title string `json:"title,omitempty"`
Items []BulkPayoutItem `json:"items"`
}
BulkPayoutParams pays up to 500 people in one call. Each item's ExternalReference becomes its payout's, so sending the same list again pays nobody twice.
type Callback ¶
type Callback struct {
// DeliveryID is the same on every retry of one delivery: record it and
// ignore a repeat.
DeliveryID string `json:"-"`
// Timestamp is when this attempt was signed.
Timestamp time.Time `json:"-"`
Event string `json:"event"`
// Reference is your external reference (Sabi's when you gave none);
// SabiReference is always Sabi's. ExternalReference repeats yours.
Reference string `json:"reference"`
SabiReference string `json:"sabi_reference"`
ExternalReference string `json:"external_reference"`
ProviderRef string `json:"provider_ref"`
Type string `json:"type"`
Status string `json:"status"`
Application string `json:"application"`
Currency string `json:"currency"`
// Amount is the principal, Net what reached the beneficiary, Total
// what the payer was charged, FeeTotal every fee -- all decimal strings.
Amount string `json:"amount"`
Net string `json:"net"`
FeeTotal string `json:"fee_total"`
Total string `json:"total"`
// AmountMinor is the net of a collection or the principal of a payout,
// in minor units. Prefer the decimal fields.
AmountMinor int64 `json:"amount_minor"`
PayerName string `json:"payer_name"`
PayerBankCode string `json:"payer_bank_code"`
// PayerAccount is the account the payer paid from; a card number is
// only ever its first six and last four digits.
PayerAccount string `json:"payer_account"`
FailureReason string `json:"failure_reason"`
ValueDate string `json:"value_date"`
// Mode is "live" or "test": whether the money is real.
Mode string `json:"mode"`
// PaymentMethod is the channel a collection was paid with.
PaymentMethod string `json:"payment_method"`
// RefundOf is the payment a refund returns money from.
RefundOf string `json:"refund_of"`
// Dispute is set on the dispute.* events.
Dispute *CallbackDispute `json:"dispute,omitempty"`
}
Callback is what Sabi posts to your callback URL.
func VerifyCallback ¶
func VerifyCallback(secret string, header http.Header, body []byte, opts VerifyOptions) (*Callback, error)
VerifyCallback checks that body was sent by Sabi, under secret, recently, and decodes it. Call it with the raw bytes of the request body, before anything else reads them.
type CallbackConfig ¶
type CallbackConfig struct {
URL string `json:"url"`
Enabled bool `json:"enabled"`
// Events are the optional events you have chosen; CoreEvents are sent
// to every client and OptionalEvents may be chosen.
Events []string `json:"events"`
CoreEvents []string `json:"core_events"`
OptionalEvents []string `json:"optional_events"`
}
CallbackConfig is where callbacks are posted.
type CallbackDelivery ¶
type CallbackDelivery struct {
ID string `json:"id"`
Event string `json:"event"`
Status string `json:"status"`
URL string `json:"url"`
Attempts int `json:"attempts"`
LastStatus *int `json:"last_status,omitempty"`
LastError string `json:"last_error,omitempty"`
NextAttemptAt *time.Time `json:"next_attempt_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
CallbackDelivery is one attempt to notify you.
type CallbackDispute ¶
type CallbackDispute struct {
Reference string `json:"reference"`
Reason string `json:"reason"`
Amount string `json:"amount"`
Status string `json:"status"`
RespondBy string `json:"respond_by"`
}
CallbackDispute is the dispute a dispute.* event is about. RespondBy is the RFC 3339 deadline for the merchant's evidence.
type CallbackTest ¶
type CallbackTest struct {
URL string `json:"url"`
Delivered bool `json:"delivered"`
Status *int `json:"status,omitempty"`
Error string `json:"error,omitempty"`
DurationMS int64 `json:"duration_ms"`
}
CallbackTest is how a test delivery went.
type ChargeResult ¶
type ChargeResult struct {
// Status is "succeeded" or "declined".
Status string `json:"status"`
Reference string `json:"reference"`
ProviderRef string `json:"provider_ref,omitempty"`
FailureReason string `json:"failure_reason,omitempty"`
Session CheckoutSession `json:"session"`
}
ChargeResult is what the checkout made of a payer's attempt.
type CheckoutSession ¶
type CheckoutSession struct {
Reference string `json:"reference"`
Narrative string `json:"narrative,omitempty"`
PayingTo string `json:"paying_to,omitempty"`
PayerName string `json:"payer_name,omitempty"`
Amount string `json:"amount"`
Lines []struct {
Label string `json:"label"`
Rate string `json:"rate,omitempty"`
Amount string `json:"amount"`
Payer string `json:"payer"`
} `json:"lines"`
Total string `json:"total"`
Currency string `json:"currency"`
Status string `json:"status"`
Payable bool `json:"payable"`
ExpiresAt time.Time `json:"expires_at"`
SettledAt *time.Time `json:"settled_at,omitempty"`
Simulated bool `json:"simulated"`
Channels []PaymentMethod `json:"channels"`
ReturnURL string `json:"return_url,omitempty"`
}
CheckoutSession is what the hosted checkout shows a payer, for a native application drawing its own.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client calls the Sabi API with one API key. It is safe for concurrent use.
func New ¶
New returns a client for the Sabi deployment at baseURL (such as https://pay.example.et), authenticating with apiKey.
func (*Client) Account ¶
Account returns who the key belongs to, whether it moves real money, and its balances.
func (*Client) Block ¶
Block refuses an account, IP address or email on your traffic: a checkout attempt from it is declined and a withdrawal to it refused.
func (*Client) Blocklist ¶
Blocklist lists the values you have blocked, newest first, a page at a time.
func (*Client) CallbackURL ¶
func (c *Client) CallbackURL(ctx context.Context) (*CallbackConfig, error)
CallbackURL returns where your callbacks are posted.
func (*Client) CancelPayment ¶
CancelPayment closes a payment nobody has paid, so its checkout stops taking money. Cancelling one already cancelled returns it unchanged.
func (*Client) Charge ¶
func (c *Client) Charge(ctx context.Context, reference, channel, account, payerName string) (*ChargeResult, error)
Charge pays a payment at the checkout on the payer's behalf, from the channel and account they entered in your own form. Never retried: a charge is money leaving a person's account.
func (*Client) CheckoutSession ¶
CheckoutSession returns what the hosted checkout would show the payer of a payment, for an application drawing its own checkout. It needs no API key: the payment reference is the payer's credential.
func (*Client) CloseVirtualAccount ¶
CloseVirtualAccount stops a virtual account taking transfers.
func (*Client) CreateBulkPayout ¶
func (c *Client) CreateBulkPayout(ctx context.Context, p BulkPayoutParams) (*PayoutBatch, error)
CreateBulkPayout pays a list in one call and returns the batch, row by row. It is safe to retry: every item is idempotent on its reference.
func (*Client) CreatePayment ¶
func (c *Client) CreatePayment(ctx context.Context, p CreatePaymentParams) (*Transaction, error)
CreatePayment raises a collection and returns it with its fee breakdown and CheckoutURL. Repeating it with the same ExternalReference returns the same payment -- re-issued if it is still unpaid -- so it is retried safely.
func (*Client) CreatePayout ¶
func (c *Client) CreatePayout(ctx context.Context, p CreatePayoutParams) (*Transaction, error)
CreatePayout sends money from your settlement balance to a bank account or wallet. Repeating it with the same ExternalReference never pays twice.
func (*Client) CreateSubaccount ¶
func (c *Client) CreateSubaccount(ctx context.Context, p CreateSubaccountParams) (*Subaccount, error)
CreateSubaccount adds a partner that takes a share of the payments that name it.
func (*Client) CreateTransfer ¶
func (c *Client) CreateTransfer(ctx context.Context, p CreateTransferParams) (*Transaction, error)
CreateTransfer moves money to another Sabi client, at once.
func (*Client) Currencies ¶
Currencies lists the currencies Sabi holds and what each is used for.
func (*Client) DeactivateSubaccount ¶
DeactivateSubaccount switches a partner off; it keeps what it was paid.
func (*Client) EmbedOrigins ¶
func (c *Client) EmbedOrigins(ctx context.Context) (*EmbedOrigins, error)
EmbedOrigins returns the websites allowed to show your checkout in a pop-over with sabi.js.
func (*Client) GetMerchant ¶
GetMerchant returns how one of your merchants stands.
func (*Client) GetPayment ¶
GetPayment returns one of your payments by Sabi's reference or yours.
func (*Client) GetPayoutBatch ¶
GetPayoutBatch returns a bulk payout, with how each payout stands now.
func (*Client) GetSubaccount ¶
GetSubaccount returns one of your partners.
func (*Client) GetTransaction ¶
GetTransaction returns one of your transactions of any kind.
func (*Client) ListAllRefunds ¶
func (c *Client) ListAllRefunds(ctx context.Context, p ListParams) (*Page[Transaction], error)
ListAllRefunds lists every refund you have sent, whatever payment it was against, newest first.
func (*Client) ListCallbacks ¶
func (c *Client) ListCallbacks(ctx context.Context, status string, limit, offset int) (*Page[CallbackDelivery], error)
ListCallbacks lists every attempt to notify you, newest first. status may be "", pending, delivered or dead.
func (*Client) ListPayments ¶
func (c *Client) ListPayments(ctx context.Context, p ListParams) (*Page[Transaction], error)
ListPayments lists your collections, newest first.
func (*Client) ListPayouts ¶
func (c *Client) ListPayouts(ctx context.Context, p ListParams) (*Page[Transaction], error)
ListPayouts lists money you have sent out, newest first.
func (*Client) ListRefunds ¶
ListRefunds returns a payment's refunds and what is left to refund.
func (*Client) ListSubaccounts ¶
func (c *Client) ListSubaccounts(ctx context.Context) ([]Subaccount, error)
ListSubaccounts lists your partners, newest first.
func (*Client) ListTransactions ¶
func (c *Client) ListTransactions(ctx context.Context, p ListParams) (*Page[Transaction], error)
ListTransactions lists every kind of transaction, newest first.
func (*Client) ListVirtualAccounts ¶
func (c *Client) ListVirtualAccounts(ctx context.Context, status string, limit, offset int) (*Page[VirtualAccount], error)
ListVirtualAccounts lists your virtual accounts, newest first. status may be "", active, expired or closed.
func (*Client) OpenVirtualAccount ¶
func (c *Client) OpenVirtualAccount(ctx context.Context, p VirtualAccountParams) (*VirtualAccount, error)
OpenVirtualAccount opens a bank account number for one of your customers, or returns the one already open under the same external reference.
func (*Client) PaymentMethods ¶
func (c *Client) PaymentMethods(ctx context.Context) ([]PaymentMethod, error)
PaymentMethods lists the channels payers can pay with and payouts can go to, with the rule each account number follows.
func (*Client) Rate ¶
Rate returns the rate between ETB and USD in the direction asked, and what amount (a decimal string, optional) becomes at it.
func (*Client) RefundPayment ¶
func (c *Client) RefundPayment(ctx context.Context, reference string, p RefundParams) (*Transaction, error)
RefundPayment sends some or all of a paid payment back to the account the payer paid from. It returns the refund, a payout of type refund.
func (*Client) RegisterMerchant ¶
func (c *Client) RegisterMerchant(ctx context.Context, p RegisterMerchantParams) (*RegisteredMerchant, error)
RegisterMerchant opens a Sabi merchant for a business your platform hosts and returns its credentials. Only a partner client may call it. Repeating it with the same ExternalReference returns the same merchant with freshly issued credentials.
func (*Client) ReplayCallback ¶
ReplayCallback sends an abandoned delivery again.
func (*Client) SetCallback ¶
func (c *Client) SetCallback(ctx context.Context, callbackURL string, events []string) (*CallbackConfig, error)
SetCallback sets where callbacks go and which optional events (the Event* constants from EventPaymentCancelled on) are sent there. A nil events keeps the ones chosen before; an empty slice chooses none.
func (*Client) SetCallbackURL ¶
SetCallbackURL sets where your callbacks are posted; empty turns them off.
func (*Client) SetEmbedOrigins ¶
SetEmbedOrigins replaces those websites, as scheme://host[:port]; none switches embedding off.
func (*Client) SetSettlementAccount ¶
func (c *Client) SetSettlementAccount(ctx context.Context, externalReference string, p SettlementAccountParams) (*MerchantSettlement, error)
SetSettlementAccount records where a merchant is paid.
func (*Client) SetSettlementSchedule ¶
func (c *Client) SetSettlementSchedule(ctx context.Context, externalReference string, p SettlementScheduleParams) (*MerchantSettlement, error)
SetSettlementSchedule chooses when a merchant's live balance is paid to its settlement account: manual, daily, weekly or monthly.
func (*Client) SettlementAccount ¶
func (c *Client) SettlementAccount(ctx context.Context, externalReference string) (*MerchantSettlement, error)
SettlementAccount returns where a merchant is paid.
func (*Client) SimulatorSettle ¶
SimulatorSettle settles a pending payment or payout now. It exists only on a sandbox deployment, where no real money moves.
func (*Client) StartPaymentOTP ¶ added in v1.3.0
func (c *Client) StartPaymentOTP(ctx context.Context, reference string, p StartPaymentOTPInput) (*PaymentOTP, error)
StartPaymentOTP starts paying one of your pending payments straight from the payer's mobile-money wallet (telebirr, cbe_birr or mpesa): Sabi texts the payer a six-digit code, the payer reads it out, and you pass it to VerifyPaymentOTP. Asking again voids the earlier code. Never retried: each call texts the payer.
func (*Client) Statement ¶
Statement returns every settled movement on your settlement account on one day (UTC), for reconciliation. A zero date means today.
func (*Client) TestCallback ¶
func (c *Client) TestCallback(ctx context.Context) (*CallbackTest, error)
TestCallback sends a signed ping to your callback URL now and reports how your endpoint answered.
func (*Client) TransactionEvents ¶
TransactionEvents returns what has happened to one of your transactions: every attempt a payer made, settlement, refunds and callbacks.
func (*Client) UpdateMerchantOwner ¶
func (c *Client) UpdateMerchantOwner(ctx context.Context, externalReference string, p UpdateOwnerParams) (*Merchant, error)
UpdateMerchantOwner keeps the owner's sign-in in step with your platform.
func (*Client) VerifyPaymentOTP ¶ added in v1.3.0
func (c *Client) VerifyPaymentOTP(ctx context.Context, reference, code string) (*PaymentOTPResult, error)
VerifyPaymentOTP checks the code the payer read out and, when it is right, charges their wallet. A declined charge is not an error: the result's Charge.Status is "declined" and the payment stays pending. A wrong code is an *Error with Code OTP_INVALID (see OTPAttemptsLeft). Never retried: a charge is money leaving a person's account.
func (*Client) VirtualAccount ¶
VirtualAccount fetches one of your virtual accounts.
func (*Client) VirtualAccountDeposits ¶
func (c *Client) VirtualAccountDeposits(ctx context.Context, id string, limit, offset int) (*Page[VirtualAccountDeposit], error)
VirtualAccountDeposits lists the transfers into a virtual account.
type CreatePaymentParams ¶
type CreatePaymentParams struct {
Amount string `json:"amount"`
Currency string `json:"currency"`
// Type is payment (default), escrow_funding, bid_bond or deposit.
Type string `json:"type,omitempty"`
Application string `json:"application,omitempty"`
// ExternalReference is your own id for the payment and makes the call
// idempotent. Required.
ExternalReference string `json:"external_reference"`
PayerName string `json:"payer_name,omitempty"`
Narrative string `json:"narrative,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
ReturnURL string `json:"return_url,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
Customer *Customer `json:"customer,omitempty"`
Customization *Customization `json:"customization,omitempty"`
// LineItems must add up to Amount.
LineItems []LineItem `json:"line_items,omitempty"`
// PaymentMethods offers only these channel codes, in this order.
PaymentMethods []string `json:"payment_methods,omitempty"`
// CallbackURL sends this payment's callbacks here instead of to your
// configured callback URL.
CallbackURL string `json:"callback_url,omitempty"`
// Subaccount names a partner that takes a share when the payment
// settles.
Subaccount *SubaccountSplit `json:"subaccount,omitempty"`
}
CreatePaymentParams raises a collection.
type CreatePayoutParams ¶
type CreatePayoutParams struct {
Amount string `json:"amount"`
Currency string `json:"currency"`
// Type is withdrawal (default), escrow_release or refund.
Type string `json:"type,omitempty"`
Application string `json:"application,omitempty"`
ExternalReference string `json:"external_reference"`
Narrative string `json:"narrative,omitempty"`
// BeneficiaryBankCode is a payout channel from PaymentMethods.
BeneficiaryBankCode string `json:"beneficiary_bank_code,omitempty"`
BeneficiaryAccount string `json:"beneficiary_account"`
BeneficiaryName string `json:"beneficiary_name"`
Metadata map[string]string `json:"metadata,omitempty"`
}
CreatePayoutParams sends money from your balance to an account.
type CreateSubaccountParams ¶
type CreateSubaccountParams struct {
Name string `json:"name"`
Channel string `json:"channel"`
AccountNumber string `json:"account_number"`
AccountName string `json:"account_name"`
SplitType string `json:"split_type"`
SplitValue string `json:"split_value"`
}
CreateSubaccountParams adds a partner.
type CreateTransferParams ¶
type CreateTransferParams struct {
Amount string `json:"amount"`
Currency string `json:"currency"`
Destination string `json:"destination"`
ExternalReference string `json:"external_reference"`
Narrative string `json:"narrative,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}
CreateTransferParams moves money to another Sabi client.
type Currency ¶
type Currency struct {
Code string `json:"code"`
Name string `json:"name"`
Decimals int `json:"decimals"`
Collections bool `json:"collections"`
Payouts bool `json:"payouts"`
Swaps bool `json:"swaps"`
}
Currency is one currency Sabi holds and what it can be used for.
type Customer ¶
type Customer struct {
Name string `json:"name,omitempty"`
FirstName string `json:"first_name,omitempty"`
LastName string `json:"last_name,omitempty"`
Email string `json:"email,omitempty"`
PhoneNumber string `json:"phone_number,omitempty"`
}
Customer describes who is paying.
type Customization ¶
type Customization struct {
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
}
Customization is how the checkout presents a payment.
type EmbedOrigins ¶
EmbedOrigins are the websites allowed to show your checkout in a pop-over, and the checkout script they load.
type Error ¶
type Error struct {
// Status is the HTTP status.
Status int
// Code is stable and part of the API contract: branch on it, never on
// Message.
Code string
Message string
// Details carries field-level problems for a 422, under "fields".
Details map[string]any
// RequestID identifies the request in Sabi's logs; quote it to support.
RequestID string
// RetryAfter is how long Sabi asked the caller to wait, on a 429.
RetryAfter time.Duration
}
Error is a failure the Sabi API reported.
type Fee ¶
type Fee struct {
Label string `json:"label"`
Type string `json:"type"`
Rate string `json:"rate"`
Amount string `json:"amount"`
// Payer is "customer" (added on top) or "recipient" (taken out).
Payer string `json:"payer"`
// Owner is who the fee is owed to: "sabi", "escrow" or "application".
Owner string `json:"owner"`
}
Fee is one line of a transaction's authoritative fee breakdown.
type FeeQuoteParams ¶
type FeeQuoteParams struct {
Amount string `json:"amount"`
Currency string `json:"currency"`
Type string `json:"type"`
Application string `json:"application,omitempty"`
}
FeeQuoteParams asks what a transaction would cost.
type LineItem ¶
type LineItem struct {
Name string `json:"name"`
Quantity int64 `json:"quantity,omitempty"`
UnitAmount string `json:"unit_amount"`
Amount string `json:"amount,omitempty"`
}
LineItem is one line of what a payment is for. UnitAmount is a decimal string; Amount (in answers) is the line's total.
type ListParams ¶
type ListParams struct {
Status string
Type string
// Direction applies to ListTransactions only: in, out or internal.
Direction string
// Search matches references, the narrative and the payer's name.
Search string
// From and To bound when the transaction was raised: From inclusive,
// To exclusive.
From, To time.Time
Limit int
Offset int
}
ListParams narrows and pages a listing. Zero values are left out.
type Merchant ¶
type Merchant struct {
MerchantNumber int64 `json:"merchant_number"`
ExternalReference string `json:"external_reference"`
BusinessName string `json:"business_name"`
VerificationStatus string `json:"verification_status"`
LiveStatus string `json:"live_status"`
SignIn MerchantSignIn `json:"sign_in"`
SettlementAccount *SettlementAccount `json:"settlement_account"`
}
Merchant is how one of a partner's merchants stands.
type MerchantCredentials ¶
type MerchantCredentials struct {
Client string `json:"client"`
Status string `json:"status"`
APIKey string `json:"api_key"`
CallbackSecret string `json:"callback_secret"`
}
MerchantCredentials are one of a merchant's two clients.
type MerchantSettlement ¶
type MerchantSettlement struct {
MerchantNumber int64 `json:"merchant_number"`
ExternalReference string `json:"external_reference"`
SettlementAccount *SettlementAccount `json:"settlement_account"`
}
MerchantSettlement is a merchant's settlement account, which is nil when none has been set.
type MerchantSignIn ¶
type MerchantSignIn struct {
Phone string `json:"phone"`
Email string `json:"email,omitempty"`
Password bool `json:"password"`
URL string `json:"url"`
}
MerchantSignIn is how a merchant's owner reaches the portal.
type NetworkError ¶
type NetworkError struct{ Err error }
NetworkError is a request that got no answer from Sabi at all: the connection failed or timed out. Whether it was acted on is unknown, so a money call that fails this way must be looked up by its external reference before it is raised again.
func (*NetworkError) Error ¶
func (e *NetworkError) Error() string
func (*NetworkError) Timeout ¶
func (e *NetworkError) Timeout() bool
Timeout reports whether the request timed out.
func (*NetworkError) Unwrap ¶
func (e *NetworkError) Unwrap() error
type Option ¶
type Option func(*Client)
Option changes how a Client is built.
func WithHTTPClient ¶
WithHTTPClient sends requests through c instead of a client with a 30-second timeout.
func WithMaxRetries ¶
WithMaxRetries sets how many times a request that is safe to repeat is retried after a temporary failure. The default is 2; 0 turns retries off.
func WithUserAgent ¶
WithUserAgent names your application in the User-Agent Sabi logs, before this library's own name.
type Page ¶
type Page[T any] struct { Data []T `json:"data"` Total int `json:"total"` Limit int `json:"limit"` Offset int `json:"offset"` }
Page is one page of a listing.
type PaymentMethod ¶
type PaymentMethod struct {
Code string `json:"code"`
Name string `json:"name"`
Kind string `json:"kind"`
Collect bool `json:"collect"`
Payout bool `json:"payout"`
AccountLabel string `json:"account_label"`
AccountHint string `json:"account_hint"`
Account AccountRule `json:"account"`
}
PaymentMethod is a channel money can come in or go out through.
type PaymentOTP ¶ added in v1.3.0
type PaymentOTP struct {
Reference string `json:"reference"`
Channel string `json:"channel"`
AccountMasked string `json:"account_masked"`
// Amount is what the payer will be charged, fees included.
Amount string `json:"amount"`
Currency string `json:"currency"`
ExpiresAt time.Time `json:"expires_at"`
// StandInCode is the code itself, present only when the Sabi you are
// talking to simulates SMS (development and test). Never set with a
// real SMS provider.
StandInCode string `json:"stand_in_code,omitempty"`
}
PaymentOTP is a code on its way to a payer's phone.
type PaymentOTPCharge ¶ added in v1.3.0
type PaymentOTPCharge struct {
// Status is "succeeded" or "declined".
Status string `json:"status"`
FailureReason string `json:"failure_reason,omitempty"`
}
PaymentOTPCharge is how the wallet answered.
func (PaymentOTPCharge) Succeeded ¶ added in v1.3.0
func (c PaymentOTPCharge) Succeeded() bool
Succeeded reports whether the payer's money was taken.
type PaymentOTPResult ¶ added in v1.3.0
type PaymentOTPResult struct {
// Payment is the payment after the charge, as GetPayment returns it.
Payment Transaction `json:"payment"`
Charge PaymentOTPCharge `json:"charge"`
}
PaymentOTPResult is a verified code and the charge it authorised.
type PayoutBatch ¶
type PayoutBatch struct {
ID string `json:"id"`
Title string `json:"title"`
Status string `json:"status"`
Currency string `json:"currency"`
Items int `json:"items"`
Valid int `json:"valid"`
Sent int `json:"sent"`
Failed int `json:"failed"`
Total string `json:"total"`
CreatedAt time.Time `json:"created_at"`
Rows []PayoutBatchRow `json:"rows"`
}
PayoutBatch is a bulk payout, row by row.
type PayoutBatchRow ¶
type PayoutBatchRow struct {
Row int `json:"row"`
ExternalReference string `json:"external_reference"`
Status string `json:"status"`
Error string `json:"error,omitempty"`
Reference string `json:"reference,omitempty"`
PayoutStatus string `json:"payout_status,omitempty"`
Amount string `json:"amount"`
BeneficiaryBankCode string `json:"beneficiary_bank_code"`
BeneficiaryName string `json:"beneficiary_name"`
BeneficiaryAccountMasked string `json:"beneficiary_account_masked"`
}
PayoutBatchRow is one item: invalid (never sent), failed (refused when sent), or sent, when PayoutStatus says how its payout stands.
type Quote ¶
type Quote struct {
Amount string `json:"amount"`
Currency string `json:"currency"`
Type string `json:"type"`
Fees []Fee `json:"fees"`
FeeTotal string `json:"fee_total"`
Total string `json:"total"`
Net string `json:"net"`
}
Quote is a fee breakdown for a transaction that has not been raised.
type Rate ¶
type Rate struct {
From string `json:"from"`
To string `json:"to"`
Rate string `json:"rate"`
Amount string `json:"amount,omitempty"`
Converted string `json:"converted,omitempty"`
RateID string `json:"rate_id"`
SetAt string `json:"set_at"`
}
Rate is the exchange rate a swap is priced at now.
type RefundParams ¶
type RefundParams struct {
// Amount is optional: left empty, everything still refundable.
Amount string `json:"amount,omitempty"`
Currency string `json:"currency,omitempty"`
Reason string `json:"reason,omitempty"`
ExternalReference string `json:"external_reference"`
}
RefundParams sends money back to whoever paid a payment.
type Refunds ¶
type Refunds struct {
PaymentReference string `json:"payment_reference"`
Currency string `json:"currency"`
Refunded string `json:"refunded"`
Refundable string `json:"refundable"`
Refunds []Transaction `json:"refunds"`
}
Refunds is a payment's refunds, and what is left to refund.
type RegisterMerchantParams ¶
type RegisterMerchantParams struct {
ExternalReference string `json:"external_reference"`
BusinessName string `json:"business_name"`
BusinessType string `json:"business_type,omitempty"`
OwnerName string `json:"owner_name"`
OwnerEmail string `json:"owner_email"`
OwnerPhone string `json:"owner_phone"`
// OwnerPasswordHash is the argon2id PHC hash of the owner's password on
// your platform -- never the password.
OwnerPasswordHash string `json:"owner_password_hash,omitempty"`
CallbackURL string `json:"callback_url,omitempty"`
}
RegisterMerchantParams opens a merchant for a business a partner hosts.
type RegisteredMerchant ¶
type RegisteredMerchant struct {
MerchantNumber int64 `json:"merchant_number"`
ExternalReference string `json:"external_reference"`
BusinessName string `json:"business_name"`
VerificationStatus string `json:"verification_status"`
Created bool `json:"created"`
SignIn MerchantSignIn `json:"sign_in"`
Test MerchantCredentials `json:"test"`
Live MerchantCredentials `json:"live"`
}
RegisteredMerchant is a merchant with the credentials this call issued. They are shown once.
type SettlementAccount ¶
type SettlementAccount struct {
Channel string `json:"channel"`
AccountHint string `json:"account_hint"`
HolderName string `json:"holder_name"`
Verified bool `json:"verified"`
VerifiedAt *time.Time `json:"verified_at"`
UpdatedAt time.Time `json:"updated_at"`
// Schedule is when the merchant's live balance is paid to the account.
Schedule SettlementSchedule `json:"schedule"`
}
SettlementAccount is where a merchant is paid, masked.
type SettlementAccountParams ¶
type SettlementAccountParams struct {
Channel string `json:"channel"`
AccountNumber string `json:"account_number"`
HolderName string `json:"holder_name"`
}
SettlementAccountParams is where a merchant is paid.
type SettlementSchedule ¶
type SettlementSchedule struct {
// Frequency is manual, daily, weekly or monthly.
Frequency string `json:"frequency"`
Weekday int `json:"weekday"`
DayOfMonth int `json:"day_of_month"`
MinimumAmount string `json:"minimum_amount"`
ReserveAmount string `json:"reserve_amount"`
Description string `json:"description"`
// NextSettlementOn is YYYY-MM-DD, or nil when paid by hand only or the
// account is not yet verified.
NextSettlementOn *string `json:"next_settlement_on"`
}
SettlementSchedule is when a merchant's live balance is paid out.
type SettlementScheduleParams ¶
type SettlementScheduleParams struct {
Frequency string `json:"frequency"`
Weekday int `json:"weekday,omitempty"`
DayOfMonth int `json:"day_of_month,omitempty"`
MinimumAmount string `json:"minimum_amount,omitempty"`
ReserveAmount string `json:"reserve_amount,omitempty"`
}
SettlementScheduleParams chooses when a merchant is paid. Weekday (1 Monday to 7 Sunday) is for weekly and DayOfMonth (1 to 31) for monthly.
type StartPaymentOTPInput ¶ added in v1.3.0
type StartPaymentOTPInput struct {
// Channel is telebirr, cbe_birr or mpesa. Bank and card payments go
// through the hosted checkout.
Channel string `json:"channel"`
// Account is the wallet's phone number, in any usual spelling.
Account string `json:"account"`
}
StartPaymentOTPInput names the mobile-money wallet to charge.
type Statement ¶
type Statement struct {
Date string `json:"date"`
Lines []StatementLine `json:"lines"`
}
Statement is every settled movement on your settlement account on one day.
type StatementLine ¶
type StatementLine struct {
ProviderRef string `json:"provider_ref"`
// Direction is credit or debit, from your side.
Direction string `json:"direction"`
Amount string `json:"amount"`
Currency string `json:"currency"`
Reference string `json:"reference"`
Narrative string `json:"narrative,omitempty"`
Counterparty string `json:"counterparty,omitempty"`
ValueDate time.Time `json:"value_date"`
}
StatementLine is one of them, as your reconciliation reads it.
type Subaccount ¶
type Subaccount struct {
ID string `json:"id"`
Name string `json:"name"`
Channel string `json:"channel"`
AccountMasked string `json:"account_masked"`
AccountName string `json:"account_name"`
// SplitType is "percentage" (SplitValue "10.00" is 10%) or "flat".
SplitType string `json:"split_type"`
SplitValue string `json:"split_value"`
Currency string `json:"currency"`
Active bool `json:"active"`
// Splits is how many payments have paid it a share, Shared how much.
Splits int `json:"splits"`
CreatedAt time.Time `json:"created_at"`
}
Subaccount is a partner that takes a share of the payments that name it.
type SubaccountSplit ¶
type SubaccountSplit struct {
ID string `json:"id"`
SplitType string `json:"split_type,omitempty"`
SplitValue string `json:"split_value,omitempty"`
}
SubaccountSplit names a partner on a payment, at its own split or, with SplitType and SplitValue, at one for this payment only.
type Timeline ¶
type Timeline struct {
Reference string `json:"reference"`
Status string `json:"status"`
Events []TimelineEvent `json:"events"`
}
Timeline is what has happened to one transaction, oldest first.
type TimelineEvent ¶
type TimelineEvent struct {
At time.Time `json:"at"`
Event string `json:"event"`
Summary string `json:"summary"`
Detail map[string]string `json:"detail,omitempty"`
}
TimelineEvent is one step of it: created, attempt_succeeded, attempt_declined, settled, refunded, callback_delivered and so on.
type Transaction ¶
type Transaction struct {
// Reference is Sabi's own; ExternalReference is yours.
Reference string `json:"reference"`
ExternalReference string `json:"external_reference,omitempty"`
Type string `json:"type"`
Direction string `json:"direction"`
Status string `json:"status"`
Currency string `json:"currency"`
// Amount is the principal; Total is what the payer is charged (or what
// leaves your balance, for a payout); Net is what the beneficiary
// receives. FeeTotal is every fee, whoever bears it.
Amount string `json:"amount"`
FeeTotal string `json:"fee_total"`
Total string `json:"total"`
Net string `json:"net"`
Fees []Fee `json:"fees"`
Narrative string `json:"narrative,omitempty"`
PayerName string `json:"payer_name,omitempty"`
Application string `json:"application,omitempty"`
BeneficiaryName string `json:"beneficiary_name,omitempty"`
BeneficiaryAccountMasked string `json:"beneficiary_account_masked,omitempty"`
// CheckoutURL is where the payer pays a collection.
CheckoutURL string `json:"checkout_url,omitempty"`
ProviderRef string `json:"provider_ref,omitempty"`
FailureReason string `json:"failure_reason,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
SettledAt *time.Time `json:"settled_at,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
Title string `json:"title,omitempty"`
Customer *Customer `json:"customer,omitempty"`
LineItems []LineItem `json:"line_items,omitempty"`
// PaymentMethods are the channels the checkout offers, when restricted.
PaymentMethods []string `json:"payment_methods,omitempty"`
// PaymentMethod is the channel that paid a settled payment, and
// PayerAccountMasked the account it was paid from.
PaymentMethod string `json:"payment_method,omitempty"`
PayerAccountMasked string `json:"payer_account_masked,omitempty"`
// CallbackURL is where this transaction's callbacks go, when you set
// one for it.
CallbackURL string `json:"callback_url,omitempty"`
// QRCodeURL is an SVG QR code of CheckoutURL, while the payment can be
// made.
QRCodeURL string `json:"qr_code_url,omitempty"`
}
Transaction is one movement of money: a payment (direction "in"), a payout or refund ("out") or a transfer ("internal").
func (*Transaction) Settled ¶
func (t *Transaction) Settled() bool
Settled reports whether the money has moved.
type UpdateOwnerParams ¶
type UpdateOwnerParams struct {
OwnerName *string `json:"owner_name,omitempty"`
OwnerEmail *string `json:"owner_email,omitempty"`
OwnerPasswordHash *string `json:"owner_password_hash,omitempty"`
}
UpdateOwnerParams keeps the owner's sign-in in step with the partner's. A nil field is left as it is.
type VerifyOptions ¶
type VerifyOptions struct {
// Tolerance is how far a callback's timestamp may be from now; zero
// means DefaultTolerance.
Tolerance time.Duration
// Now is the clock; nil means time.Now.
Now func() time.Time
// AllowLegacy accepts a callback that carries only the older body-only
// signature, for a Sabi deployment that predates the V2 header. It
// gives up replay protection; leave it off.
AllowLegacy bool
}
VerifyOptions changes how a callback is checked.
type VirtualAccount ¶
type VirtualAccount struct {
ID string `json:"id"`
ExternalReference string `json:"external_reference"`
AccountName string `json:"account_name"`
AccountNumber string `json:"account_number"`
BankCode string `json:"bank_code"`
BankName string `json:"bank_name"`
Currency string `json:"currency"`
// Status is active, expired or closed.
Status string `json:"status"`
ExpectedAmount *string `json:"expected_amount"`
SingleUse bool `json:"single_use"`
ExpiresAt *time.Time `json:"expires_at"`
ClosedAt *time.Time `json:"closed_at"`
CustomerEmail string `json:"customer_email,omitempty"`
CustomerPhone string `json:"customer_phone,omitempty"`
Received string `json:"received"`
Deposits int `json:"deposits"`
Metadata map[string]string `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
VirtualAccount is a bank account number opened for one of your customers: transfers into it are credited to you as payments.
type VirtualAccountDeposit ¶
type VirtualAccountDeposit struct {
ID string `json:"id"`
BankReference string `json:"bank_reference"`
Amount string `json:"amount"`
Currency string `json:"currency"`
PayerName string `json:"payer_name,omitempty"`
PayerChannel string `json:"payer_channel,omitempty"`
PayerAccount string `json:"payer_account,omitempty"`
// Status is credited, or refused for the bank to return.
Status string `json:"status"`
RefusalReason string `json:"refusal_reason,omitempty"`
PaymentReference string `json:"payment_reference,omitempty"`
ReceivedAt time.Time `json:"received_at"`
}
VirtualAccountDeposit is one transfer into a virtual account.
type VirtualAccountParams ¶
type VirtualAccountParams struct {
ExternalReference string `json:"external_reference"`
AccountName string `json:"account_name"`
CustomerEmail string `json:"customer_email,omitempty"`
CustomerPhone string `json:"customer_phone,omitempty"`
ExpectedAmount string `json:"expected_amount,omitempty"`
SingleUse bool `json:"single_use,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}
VirtualAccountParams opens a virtual account. ExternalReference makes the call idempotent.