bayarcash

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 22, 2026 License: MIT Imports: 20 Imported by: 0

README

Bayarcash Payment Gateway Go SDK

Go Reference Go Report Card License

The Bayarcash SDK provides an idiomatic Go interface for interacting with Bayarcash's Payment Gateway API. It supports both API v2 (default) and v3, with additional query features available in v3. It is a feature-parity port of the official Bayarcash PHP SDK and depends only on the Go standard library.

Table of Contents

Requirements

  • Go 1.21 or newer
  • No external dependencies (standard library only)

Installation

go get github.com/bayarcash/go-sdk
import bayarcash "github.com/bayarcash/go-sdk"

You will need two credentials from your Bayarcash console:

  • API token — used to authenticate SDK requests.
  • API secret key — used to generate request checksums and verify callbacks.

Getting Started

client := bayarcash.New("YOUR_API_TOKEN",
    bayarcash.WithSecretKey("YOUR_API_SECRET_KEY"),
    bayarcash.WithSandbox(true), // remove in production
)

Every request method takes a context.Context as its first argument.

Configuration

Configuration can be supplied as functional options to New:

client := bayarcash.New("YOUR_API_TOKEN",
    bayarcash.WithSecretKey("YOUR_API_SECRET_KEY"),
    bayarcash.WithSandbox(true),          // switch to the sandbox environment
    bayarcash.WithAPIVersion("v3"),       // "v2" (default) or "v3"
    bayarcash.WithTimeout(60*time.Second), // request timeout (default 30s)
)

…or applied fluently after construction (call these before making requests):

client.UseSandbox().SetAPIVersion("v3").SetTimeout(60 * time.Second)
client.GetAPIVersion() // read back the current version

Omit WithSandbox(true) / UseSandbox() in production to hit the live gateway.

The base URIs used per environment and version are:

Version Production Sandbox
v2 https://console.bayar.cash/api/v2/ https://console.bayarcash-sandbox.com/api/v2/
v3 https://api.console.bayar.cash/v3/ https://api.console.bayarcash-sandbox.com/v3/

Quick Start: Accept a Payment

A complete FPX payment flow, from creating the payment to verifying the result:

package main

import (
    "context"
    "log"

    bayarcash "github.com/bayarcash/go-sdk"
)

func main() {
    client := bayarcash.New("YOUR_API_TOKEN",
        bayarcash.WithSecretKey("YOUR_API_SECRET_KEY"),
        bayarcash.WithSandbox(true),
    )

    // 1. Build the payment request
    req := bayarcash.PaymentIntentRequest{
        PortalKey:            "your_portal_key",
        PaymentChannel:       []int{bayarcash.FPX},
        OrderNumber:          "INV-1001",
        Amount:               "10.00",
        PayerName:            "Ahmad bin Abdullah",
        PayerEmail:           "ahmad@example.com",
        PayerTelephoneNumber: "0123456789",
        ReturnURL:            "https://your-site.com/payment/return",
        CallbackURL:          "https://your-site.com/payment/callback",
    }

    // 2. Sign it (recommended). Passing "" uses the client's configured secret key.
    req.Checksum = client.CreatePaymentIntentChecksumValue("", req)

    // 3. Create the payment intent and redirect the payer to Bayarcash
    intent, err := client.CreatePaymentIntent(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Redirect the payer to:", *intent.URL)
}

After payment, Bayarcash calls your CallbackURL (server-to-server) and redirects the payer to your ReturnURL. Verify both — see Handling Callbacks.

Payment Channels

Pass one (or several) of these constants as PaymentChannel:

bayarcash.FPX             // 1  FPX Online Banking
bayarcash.ManualTransfer  // 2  Manual Bank Transfer
bayarcash.FpxDirectDebit  // 3  FPX Direct Debit
bayarcash.FpxLineOfCredit // 4  FPX Line of Credit
bayarcash.DuitNowDOBW     // 5  DuitNow Online Banking
bayarcash.DuitNowQR       // 6  DuitNow QR
bayarcash.SPayLater       // 7  ShopeePayLater
bayarcash.BoostPayFlex    // 8  Boost PayFlex
bayarcash.QRISOB          // 9  QRIS Online Banking
bayarcash.QRISWallet      // 10 QRIS Wallet
bayarcash.NETS            // 11 NETS
bayarcash.CreditCard      // 12 Credit Card
bayarcash.Alipay          // 13 Alipay
bayarcash.WeChatPay       // 14 WeChat Pay
bayarcash.PromptPay       // 15 PromptPay
bayarcash.TouchNGo        // 16 Touch 'n Go eWallet
bayarcash.BoostWallet     // 17 Boost Wallet
bayarcash.GrabPay         // 18 GrabPay
bayarcash.GrabPL          // 19 Grab PayLater
bayarcash.ShopeePay       // 21 ShopeePay (id 20 is intentionally unused)

Creating a Payment Intent

intent, err := client.CreatePaymentIntent(ctx, req)

Request fields (PaymentIntentRequest):

Field Required Description
PortalKey ✅ Your portal key.
OrderNumber ✅ Your reference. Max 30 chars.
Amount ✅ String with up to 2 decimals, e.g. "10.00".
PayerName ✅ Max 150 chars.
PayerEmail ✅ Valid email, max 250 chars.
PaymentChannel ➖ []int of bayarcash.* channel ids. If empty, the payer chooses on the Bayarcash page.
PayerTelephoneNumber ➖ Required for e-wallet / DuitNow channels.
ReturnURL ➖ Where the payer's browser is redirected after payment.
CallbackURL ➖ Server-to-server notification URL.
Metadata ➖ map[string]string echoed back to you.
Checksum ➖ Recommended. See below.
Checksum

The checksum protects the request from tampering. Generate it after building the request and assign it:

req.Checksum = client.CreatePaymentIntentChecksumValue("", req)

The checksum is computed (HMAC-SHA256) from PaymentChannel, OrderNumber, Amount, PayerName, and PayerEmail. Passing an empty secret key uses the one configured on the client.

Handling Callbacks

Bayarcash sends two kinds of notification. Always verify them with your API secret key before trusting the data. Build a CallbackData from the incoming form or query values:

// From an *http.Request:
_ = r.ParseForm()
data := bayarcash.CallbackData{}
for k := range r.Form {
    data[k] = r.Form.Get(k)
}

// Transaction callback (sent to your CallbackURL)
if client.VerifyTransactionCallbackData(data, "") {
    // Data is authentic — safe to process.
}

// Payer redirect (sent to your ReturnURL)
if client.VerifyReturnUrlCallbackData(data, "") {
    // ...
}

// Pre-transaction callback (sent before the transaction record)
if client.VerifyPreTransactionCallbackData(data, "") {
    // ...
}

Each verifier returns true only when the checksum matches (compared in constant time). See FPX Direct Debit for mandate-specific callback verifiers.

Payment & Transaction Status

Transaction status is an integer code. Use the helpers instead of hardcoding numbers:

bayarcash.FpxStatusNew       // 0
bayarcash.FpxStatusPending   // 1
bayarcash.FpxStatusFailed    // 2
bayarcash.FpxStatusSuccess   // 3
bayarcash.FpxStatusCancelled // 4

bayarcash.FpxStatusText(bayarcash.FpxStatusSuccess) // "Successful"

DuitNow DOBW (DobwStatusText) and FPX Direct Debit (DirectDebitStatusText) have their own status helpers.

Transactions

// Get a single transaction (v2 and v3)
tx, err := client.GetTransaction(ctx, "transaction_id")

The following query helpers require API v3 and return an error on v2:

client.SetAPIVersion("v3")

list, err := client.GetAllTransactions(ctx, bayarcash.TransactionFilters{
    OrderNumber:             "INV-1001",
    Status:                  "3",
    PaymentChannel:          bayarcash.FPX,
    ExchangeReferenceNumber: "REF123",
    PayerEmail:              "ahmad@example.com",
})
// list.Data => []Transaction, list.Meta => pagination meta

byOrder, _   := client.GetTransactionByOrderNumber(ctx, "INV-1001")
byEmail, _   := client.GetTransactionsByPayerEmail(ctx, "ahmad@example.com")
byStatus, _  := client.GetTransactionsByStatus(ctx, "3")
byChannel, _ := client.GetTransactionsByPaymentChannel(ctx, bayarcash.FPX)
byRef, _     := client.GetTransactionByReferenceNumber(ctx, "REF123") // *Transaction or nil

// Get a payment intent by id (v3 only)
intent, _ := client.GetPaymentIntent(ctx, "payment_intent_id")

// Cancel a payment intent (v3 only)
_, _ = client.CancelPaymentIntent(ctx, "payment_intent_id")

FPX Direct Debit

FPX Direct Debit lets you set up a recurring mandate and later maintain or terminate it.

// Payer ID type
bayarcash.PayerIDTypeNRIC                 // 1 (New IC)
bayarcash.PayerIDTypeOldIC                // 2
bayarcash.PayerIDTypePassport             // 3
bayarcash.PayerIDTypeBusinessRegistration // 4
bayarcash.PayerIDTypeOthers               // 5

// Frequency mode
bayarcash.FrequencyModeDaily   // "DL"
bayarcash.FrequencyModeWeekly  // "WK"
bayarcash.FrequencyModeMonthly // "MT"
bayarcash.FrequencyModeYearly  // "YR"
1. Enrolment
req := bayarcash.DirectDebitEnrolmentRequest{
    PortalKey:            "your_portal_key",
    OrderNumber:          "DD-1001",
    Amount:               "10.00",
    PayerName:            "Ahmad bin Abdullah",
    PayerIDType:          bayarcash.PayerIDTypeNRIC,
    PayerID:              "900101011234",
    PayerEmail:           "ahmad@example.com",
    PayerTelephoneNumber: "0123456789",
    ApplicationReason:    "Monthly subscription",
    FrequencyMode:        bayarcash.FrequencyModeMonthly,
    EffectiveDate:        "2026-08-01", // optional
    ExpiryDate:           "2027-08-01", // optional
    ReturnURL:            "https://your-site.com/mandate/return",
}
req.Checksum = client.CreateFpxDirectDebitEnrolmentChecksumValue("", req)

mandate, err := client.CreateFpxDirectDebitEnrollment(ctx, req)
// redirect the payer to *mandate.URL
2. Maintenance
req := bayarcash.DirectDebitMaintenanceRequest{
    Amount:               "15.00",
    PayerEmail:           "ahmad@example.com",
    PayerTelephoneNumber: "0123456789",
    ApplicationReason:    "Update amount",
    FrequencyMode:        bayarcash.FrequencyModeMonthly,
}
req.Checksum = client.CreateFpxDirectDebitMaintenanceChecksumValue("", req)

mandate, err := client.CreateFpxDirectDebitMaintenance(ctx, mandateID, req)
3. Termination
mandate, err := client.CreateFpxDirectDebitTermination(ctx, mandateID,
    bayarcash.DirectDebitTerminationRequest{ApplicationReason: "Customer cancelled"},
)
Retrieving mandates & verifying mandate callbacks
mandate, _     := client.GetFpxDirectDebit(ctx, mandateID)
transaction, _ := client.GetFpxDirectDebitTransaction(ctx, transactionID)

// Mandate callback verifiers
client.VerifyDirectDebitBankApprovalCallbackData(data, "")
client.VerifyDirectDebitAuthorizationCallbackData(data, "") // signs application_type
client.VerifyDirectDebitTransactionCallbackData(data, "")

Manual Bank Transfer

Submit a manual (offline) bank transfer with proof of payment:

res, err := client.CreateManualBankTransfer(ctx, bayarcash.ManualBankTransferRequest{
    PortalKey:                 "your_portal_key",
    PaymentGateway:            bayarcash.ManualTransfer, // must be 2
    OrderNo:                   "MT-1001",
    OrderAmount:               "10.00",
    BuyerName:                 "Ahmad bin Abdullah",
    BuyerEmail:                "ahmad@example.com",
    BuyerTelNo:                "0123456789", // optional
    MerchantBankName:          "Maybank",
    MerchantBankAccount:       "1234567890",
    MerchantBankAccountHolder: "Your Company Sdn Bhd",
    BankTransferType:          "Internet Banking",
    BankTransferNotes:         "Payment for order MT-1001",
    BankTransferDate:          "2026-07-22",             // optional, defaults to today
    ProofOfPayment:            "/path/to/receipt.jpg",   // jpeg/png/gif/pdf
}, false /* allowRedirect */)

The *ManualBankTransferResult reports how the gateway responded: an HTML form (res.Success, res.FormData, res.ReturnURL), a JSON body (res.JSON), a raw body (res.Raw), or an unfollowed redirect (res.IsRedirect, res.RedirectURL, res.Location).

Update the status of an existing transfer:

_, err := client.UpdateManualBankTransferStatus(ctx, "ref_no_here",
    strconv.Itoa(bayarcash.FpxStatusSuccess), "10.00")

Portals & FPX Banks

portals, _  := client.GetPortals(ctx)              // all portals for your account
channels, _ := client.GetChannels(ctx, "portal_key") // payment channels for a portal
banks, _    := client.FpxBanksList(ctx)            // FPX banks (for a bank selector)

Error Handling

Failed API calls return typed errors. Use errors.As to handle them:

intent, err := client.CreatePaymentIntent(ctx, req)
if err != nil {
    var ve *bayarcash.ValidationError
    var nf *bayarcash.NotFoundError
    var rl *bayarcash.RateLimitError
    var fa *bayarcash.FailedActionError
    switch {
    case errors.As(err, &ve):
        // 422 — invalid data; ve.Errors holds the details
    case errors.As(err, &nf):
        // 404 — resource not found
    case errors.As(err, &rl):
        // 429 — too many requests; rl.ResetsAt is a unix timestamp or nil
    case errors.As(err, &fa):
        // 400 — request failed; fa.Message has the reason
    default:
        // other non-2xx -> *bayarcash.APIError
    }
}
Error HTTP Meaning
*ValidationError 422 Invalid data. Errors holds the decoded error body.
*FailedActionError 400 Request failed. Message has the reason.
*NotFoundError 404 Resource not found.
*RateLimitError 429 Rate limited. ResetsAt holds the reset time.
*APIError other Generic API error with StatusCode and Body.
*TimeoutError — Returned by the optional Retry helper after a timeout.

Response Objects

API methods return typed structs. Fields the API omits are nil (pointers). Numeric-or-string fields (ids, amounts, statuses) use FlexString, which decodes tolerantly and exposes .String() and .Float64().

*PaymentIntent (from CreatePaymentIntent / GetPaymentIntent)

*intent.URL          // checkout URL to redirect the payer to
intent.ID            // *FlexString
intent.Status        // *FlexString
intent.Amount        // *FlexString ( .Float64() available )
*intent.OrderNumber
*intent.PayerName
*intent.PayerEmail

*Transaction (from GetTransaction / transaction queries)

tx.ID                       // *FlexString
tx.Status                   // *FlexString (status code — see Fpx constants)
*tx.StatusDescription
tx.Amount                   // *FlexString
*tx.OrderNumber
*tx.ExchangeReferenceNumber
*tx.PayerName
*tx.PayerEmail

Security Recommendations

  1. Always send a Checksum with payment and mandate requests.
  2. Verify every callback with the provided verification methods before acting on it.
  3. Store and check transaction ids to prevent duplicate processing.
  4. Use HTTPS for your ReturnURL and CallbackURL.
  5. Keep your API token and secret key out of source control.

API Documentation

For full API details, see the Official Bayarcash API Documentation.

Support

For support questions, contact Bayarcash support or open an issue in this repository.

License

Open-sourced software licensed under the MIT license.

Documentation

Overview

Package bayarcash is a Go SDK for the Bayarcash payment gateway API.

It is an idiomatic, feature-parity port of the official Bayarcash PHP SDK, mirroring its public surface and behavior. Both API v2 (the default) and v3 are supported, with the additional query features available on v3.

Getting started

client := bayarcash.New("YOUR_API_TOKEN",
    bayarcash.WithSecretKey("YOUR_API_SECRET_KEY"),
    bayarcash.WithSandbox(true), // omit in production
)

req := bayarcash.PaymentIntentRequest{
    PortalKey:      "your_portal_key",
    PaymentChannel: []int{bayarcash.FPX},
    OrderNumber:    "INV-1001",
    Amount:         "10.00",
    PayerName:      "Ahmad bin Abdullah",
    PayerEmail:     "ahmad@example.com",
}
req.Checksum = client.CreatePaymentIntentChecksumValue("", req)

intent, err := client.CreatePaymentIntent(context.Background(), req)
if err != nil {
    // handle typed errors: *ValidationError, *NotFoundError,
    // *FailedActionError, *RateLimitError, *APIError
}
// redirect the payer to *intent.URL

Checksums and callbacks

All request signing and callback verification is HMAC-SHA256 over the payload values (sorted by key, joined with "|"), byte-compatible with the gateway. Callback verification uses a constant-time comparison.

The SDK depends only on the Go standard library.

Index

Constants

View Source
const (
	FPX             = 1  // FPX Online Banking
	ManualTransfer  = 2  // Manual Bank Transfer
	FpxDirectDebit  = 3  // FPX Direct Debit
	FpxLineOfCredit = 4  // FPX Line of Credit
	DuitNowDOBW     = 5  // DuitNow Online Banking / Wallet (DOBW)
	DuitNowQR       = 6  // DuitNow QR
	SPayLater       = 7  // ShopeePayLater
	BoostPayFlex    = 8  // Boost PayFlex
	QRISOB          = 9  // QRIS Online Banking
	QRISWallet      = 10 // QRIS Wallet
	NETS            = 11 // NETS
	CreditCard      = 12 // Credit Card
	Alipay          = 13 // Alipay
	WeChatPay       = 14 // WeChat Pay
	PromptPay       = 15 // PromptPay
	TouchNGo        = 16 // Touch 'n Go eWallet
	BoostWallet     = 17 // Boost Wallet
	GrabPay         = 18 // GrabPay
	GrabPL          = 19 // Grab PayLater
	ShopeePay       = 21 // ShopeePay (note: id 20 is intentionally unused)
)

Payment channel identifiers. Pass one (or several) as the PaymentChannel of a PaymentIntentRequest. The ids mirror the gateway exactly, including the gap: there is no id 20, and ShopeePay is 21.

View Source
const (
	PayerIDTypeNRIC                 = 1 // New IC
	PayerIDTypeOldIC                = 2 // Old IC
	PayerIDTypePassport             = 3 // Passport
	PayerIDTypeBusinessRegistration = 4 // Business registration
	PayerIDTypeOthers               = 5 // Others
)

Payer ID types (FPX Direct Debit enrolment).

View Source
const (
	FrequencyModeDaily   = "DL"
	FrequencyModeWeekly  = "WK"
	FrequencyModeMonthly = "MT"
	FrequencyModeYearly  = "YR"
)

Frequency modes (FPX Direct Debit).

View Source
const (
	ApplicationTypeEnrolment   = "01"
	ApplicationTypeMaintenance = "02"
	ApplicationTypeTermination = "03"
)

Application types (FPX Direct Debit).

View Source
const (
	DobwCASA       = "01" // Current / savings account
	DobwCreditCard = "02" // Credit card
	DobwEWallet    = "03" // e-Wallet
)

DuitNow DOBW account types.

View Source
const (
	FpxStatusNew       = 0
	FpxStatusPending   = 1
	FpxStatusFailed    = 2
	FpxStatusSuccess   = 3
	FpxStatusCancelled = 4
)

FPX transaction status codes.

View Source
const (
	DirectDebitStatusNew                    = 0
	DirectDebitStatusWaitingApproval        = 1
	DirectDebitStatusFailedBankVerification = 2
	DirectDebitStatusActive                 = 3
	DirectDebitStatusTerminated             = 4
	DirectDebitStatusApproved               = 5
	DirectDebitStatusRejected               = 6
	DirectDebitStatusCancelled              = 7
	DirectDebitStatusError                  = 8
)

FPX Direct Debit status codes.

View Source
const (
	DobwStatusNew       = 0
	DobwStatusPending   = 1
	DobwStatusFailed    = 2
	DobwStatusSuccess   = 3
	DobwStatusCancelled = 4
)

DuitNow DOBW transaction status codes.

Variables

This section is empty.

Functions

func DirectDebitApplicationTypeText

func DirectDebitApplicationTypeText(applicationType string) string

DirectDebitApplicationTypeText returns the label for an application type code ("01", "02", "03"), or an empty string for an unrecognised value.

func DirectDebitFrequencyModeText

func DirectDebitFrequencyModeText(frequencyMode string) string

DirectDebitFrequencyModeText returns the label for a frequency mode code ("DL", "WK", "MT", "YR"), or an empty string for an unrecognised value.

func DirectDebitStatusText

func DirectDebitStatusText(code int) string

DirectDebitStatusText returns the human-readable label for an FPX Direct Debit status code, or "UNKNOWN STATUS" when the code is not recognised.

func DobwStatusText

func DobwStatusText(code int) string

DobwStatusText returns the human-readable label for a DuitNow DOBW status code, or "UNKNOWN STATUS" when the code is not recognised.

func FpxStatusText

func FpxStatusText(code int) string

FpxStatusText returns the human-readable label for an FPX transaction status code, or "UNKNOWN STATUS" when the code is not recognised.

Types

type APIError

type APIError struct {
	StatusCode int
	Body       string
}

APIError is returned for any other non-2xx HTTP response.

func (*APIError) Error

func (e *APIError) Error() string

type CallbackData

type CallbackData map[string]string

CallbackData is a flat set of callback fields as received from Bayarcash (typically parsed from a form POST or a URL query). Build it from, e.g., r.ParseForm() + r.PostForm, or r.URL.Query().

type Client

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

Client is a Bayarcash API client. Create one with New. A Client is safe for use by multiple goroutines only if you do not mutate its configuration (via the Set* / UseSandbox methods) after construction; configure it once, up front, as the PHP SDK does.

func New

func New(token string, opts ...Option) *Client

New creates a Bayarcash client authenticated with the given API token.

func (*Client) CancelPaymentIntent

func (c *Client) CancelPaymentIntent(ctx context.Context, paymentIntentID string) (*PaymentIntent, error)

CancelPaymentIntent cancels a payment intent by id (v3 only).

func (*Client) CreateChecksumValue

func (c *Client) CreateChecksumValue(secretKey string, payload map[string]string) string

CreateChecksumValue computes the generic checksum over payload: the values are sorted by their keys, joined with "|", and signed with HMAC-SHA256. When secretKey is empty the client's configured secret key is used.

func (*Client) CreateFpxDirectDebitEnrollment

func (c *Client) CreateFpxDirectDebitEnrollment(ctx context.Context, req DirectDebitEnrolmentRequest) (*FpxDirectDebitApplication, error)

CreateFpxDirectDebitEnrollment creates an FPX Direct Debit enrolment (mandate).

func (*Client) CreateFpxDirectDebitEnrolmentChecksumValue

func (c *Client) CreateFpxDirectDebitEnrolmentChecksumValue(secretKey string, req DirectDebitEnrolmentRequest) string

CreateFpxDirectDebitEnrolmentChecksumValue signs an FPX Direct Debit enrolment request. When secretKey is empty the client's configured secret key is used.

func (*Client) CreateFpxDirectDebitMaintenance

func (c *Client) CreateFpxDirectDebitMaintenance(ctx context.Context, mandateID string, req DirectDebitMaintenanceRequest) (*FpxDirectDebitApplication, error)

CreateFpxDirectDebitMaintenance updates (maintains) an existing FPX Direct Debit mandate.

func (*Client) CreateFpxDirectDebitMaintenanceChecksumValue

func (c *Client) CreateFpxDirectDebitMaintenanceChecksumValue(secretKey string, req DirectDebitMaintenanceRequest) string

CreateFpxDirectDebitMaintenanceChecksumValue signs an FPX Direct Debit maintenance request. When secretKey is empty the client's configured secret key is used.

func (*Client) CreateFpxDirectDebitTermination

func (c *Client) CreateFpxDirectDebitTermination(ctx context.Context, mandateID string, req DirectDebitTerminationRequest) (*FpxDirectDebitApplication, error)

CreateFpxDirectDebitTermination terminates an existing FPX Direct Debit mandate.

func (*Client) CreateManualBankTransfer

func (c *Client) CreateManualBankTransfer(ctx context.Context, req ManualBankTransferRequest, allowRedirect bool) (*ManualBankTransferResult, error)

CreateManualBankTransfer submits a manual (offline) bank transfer, optionally with a proof-of-payment file (jpeg/png/gif/pdf). When allowRedirect is false, HTTP redirects are not followed and are reported via the result's IsRedirect / RedirectURL fields.

func (*Client) CreatePaymentIntenChecksumValue deprecated

func (c *Client) CreatePaymentIntenChecksumValue(secretKey string, req PaymentIntentRequest) string

CreatePaymentIntenChecksumValue is a misspelled alias kept for parity with the PHP SDK.

Deprecated: use CreatePaymentIntentChecksumValue.

func (*Client) CreatePaymentIntent

func (c *Client) CreatePaymentIntent(ctx context.Context, req PaymentIntentRequest) (*PaymentIntent, error)

CreatePaymentIntent creates a new payment intent.

func (*Client) CreatePaymentIntentChecksumValue

func (c *Client) CreatePaymentIntentChecksumValue(secretKey string, req PaymentIntentRequest) string

CreatePaymentIntentChecksumValue signs a payment intent. It signs payment_channel (comma-joined, empty if none), order_number, amount, payer_name, and payer_email. When secretKey is empty the client's configured secret key is used.

func (*Client) FpxBanksList

func (c *Client) FpxBanksList(ctx context.Context) ([]FpxBank, error)

FpxBanksList returns the list of FPX banks.

func (*Client) GetAPIVersion

func (c *Client) GetAPIVersion() string

GetAPIVersion returns the API version currently in use.

func (*Client) GetAllTransactions

func (c *Client) GetAllTransactions(ctx context.Context, filters TransactionFilters) (*TransactionList, error)

GetAllTransactions returns transactions matching the given filters (v3 only).

func (*Client) GetChannels

func (c *Client) GetChannels(ctx context.Context, portalKey string) ([]map[string]any, error)

GetChannels returns the payment channels available for the portal identified by portalKey, or an empty slice when no such portal exists.

func (*Client) GetFpxDirectDebit

func (c *Client) GetFpxDirectDebit(ctx context.Context, id string) (*FpxDirectDebitMandate, error)

GetFpxDirectDebit returns an FPX Direct Debit mandate by id.

func (*Client) GetFpxDirectDebitTransaction

func (c *Client) GetFpxDirectDebitTransaction(ctx context.Context, id string) (*Transaction, error)

GetFpxDirectDebitTransaction returns an FPX Direct Debit transaction by id.

func (*Client) GetFpxDirectDebitransaction deprecated

func (c *Client) GetFpxDirectDebitransaction(ctx context.Context, id string) (*Transaction, error)

GetFpxDirectDebitransaction is a misspelled alias kept for parity with the PHP SDK.

Deprecated: use GetFpxDirectDebitTransaction.

func (*Client) GetPaymentIntent

func (c *Client) GetPaymentIntent(ctx context.Context, paymentIntentID string) (*PaymentIntent, error)

GetPaymentIntent returns a payment intent by id (v3 only).

func (*Client) GetPortals

func (c *Client) GetPortals(ctx context.Context) ([]Portal, error)

GetPortals returns the portals for your account.

func (*Client) GetTimeout

func (c *Client) GetTimeout() time.Duration

GetTimeout returns the request timeout.

func (*Client) GetTransaction

func (c *Client) GetTransaction(ctx context.Context, id string) (*Transaction, error)

GetTransaction returns a single transaction by id (available on v2 and v3).

func (*Client) GetTransactionByOrderNumber

func (c *Client) GetTransactionByOrderNumber(ctx context.Context, orderNumber string) ([]Transaction, error)

GetTransactionByOrderNumber returns transactions with the given order number (v3 only).

func (*Client) GetTransactionByReferenceNumber

func (c *Client) GetTransactionByReferenceNumber(ctx context.Context, referenceNumber string) (*Transaction, error)

GetTransactionByReferenceNumber returns a single transaction by exchange reference number, or nil when none matches (v3 only).

func (*Client) GetTransactionsByPayerEmail

func (c *Client) GetTransactionsByPayerEmail(ctx context.Context, email string) ([]Transaction, error)

GetTransactionsByPayerEmail returns transactions for the given payer email (v3 only).

func (*Client) GetTransactionsByPaymentChannel

func (c *Client) GetTransactionsByPaymentChannel(ctx context.Context, channel int) ([]Transaction, error)

GetTransactionsByPaymentChannel returns transactions for the given payment channel (v3 only).

func (*Client) GetTransactionsByStatus

func (c *Client) GetTransactionsByStatus(ctx context.Context, status string) ([]Transaction, error)

GetTransactionsByStatus returns transactions with the given status (v3 only).

func (*Client) ParseManualBankTransferResponse

func (c *Client) ParseManualBankTransferResponse(htmlResponse string) map[string]string

ParseManualBankTransferResponse extracts structured data (form id, return url, and hidden inputs) from an HTML form response.

func (*Client) Retry

func (c *Client) Retry(ctx context.Context, timeout time.Duration, fn func() (any, error), sleep time.Duration) (any, error)

Retry calls fn repeatedly until it returns a non-nil result or the timeout elapses, sleeping for the given interval between attempts. It mirrors the PHP SDK's retry() helper and returns a *TimeoutError on timeout. The provided context aborts the wait.

func (*Client) SetAPIVersion

func (c *Client) SetAPIVersion(version string) *Client

SetAPIVersion sets the API version ("v2" or "v3"). Returns the client for chaining.

func (*Client) SetSecretKey

func (c *Client) SetSecretKey(secretKey string) *Client

SetSecretKey updates the API secret key. Returns the client for chaining.

func (*Client) SetTimeout

func (c *Client) SetTimeout(d time.Duration) *Client

SetTimeout sets the request timeout. Returns the client for chaining.

func (*Client) SetToken

func (c *Client) SetToken(token string) *Client

SetToken updates the API token. Returns the client for chaining.

func (*Client) UpdateManualBankTransferStatus

func (c *Client) UpdateManualBankTransferStatus(ctx context.Context, refNo, status, amount string) (any, error)

UpdateManualBankTransferStatus updates the status of an existing manual bank transfer, identified by its reference number. It returns the decoded response (a map, slice, scalar, or raw string depending on the gateway).

func (*Client) UseSandbox

func (c *Client) UseSandbox() *Client

UseSandbox switches the client to the sandbox environment. Returns the client for chaining.

func (*Client) VerifyDirectDebitAuthorizationCallbackData

func (c *Client) VerifyDirectDebitAuthorizationCallbackData(callbackData CallbackData, secretKey string) bool

VerifyDirectDebitAuthorizationCallbackData verifies a direct-debit authorization callback. The signed payload includes application_type.

func (*Client) VerifyDirectDebitBankApprovalCallbackData

func (c *Client) VerifyDirectDebitBankApprovalCallbackData(callbackData CallbackData, secretKey string) bool

VerifyDirectDebitBankApprovalCallbackData verifies a direct-debit bank approval callback.

func (*Client) VerifyDirectDebitTransactionCallbackData

func (c *Client) VerifyDirectDebitTransactionCallbackData(callbackData CallbackData, secretKey string) bool

VerifyDirectDebitTransactionCallbackData verifies a direct-debit transaction callback.

func (*Client) VerifyPreTransactionCallbackData

func (c *Client) VerifyPreTransactionCallbackData(callbackData CallbackData, secretKey string) bool

VerifyPreTransactionCallbackData verifies a pre-transaction callback.

func (*Client) VerifyReturnUrlCallbackData

func (c *Client) VerifyReturnUrlCallbackData(callbackData CallbackData, secretKey string) bool

VerifyReturnUrlCallbackData verifies a return-url callback (the payer redirect).

func (*Client) VerifyTransactionCallbackData

func (c *Client) VerifyTransactionCallbackData(callbackData CallbackData, secretKey string) bool

VerifyTransactionCallbackData verifies a transaction callback (sent to your callback_url).

type DirectDebitEnrolmentRequest

type DirectDebitEnrolmentRequest struct {
	PortalKey            string
	OrderNumber          string
	Amount               string
	PayerName            string
	PayerIDType          int // one of the PayerIDType* constants
	PayerID              string
	PayerEmail           string
	PayerTelephoneNumber string
	ApplicationReason    string
	FrequencyMode        string // one of the FrequencyMode* constants
	EffectiveDate        string // optional, "YYYY-MM-DD"
	ExpiryDate           string // optional, "YYYY-MM-DD"
	ReturnURL            string
	Checksum             string
	Extra                map[string]string
}

DirectDebitEnrolmentRequest describes an FPX Direct Debit enrolment (mandate creation).

type DirectDebitMaintenanceRequest

type DirectDebitMaintenanceRequest struct {
	Amount               string
	PayerEmail           string
	PayerTelephoneNumber string
	ApplicationReason    string
	FrequencyMode        string
	Checksum             string
	Extra                map[string]string
}

DirectDebitMaintenanceRequest describes an update to an existing FPX Direct Debit mandate.

type DirectDebitTerminationRequest

type DirectDebitTerminationRequest struct {
	ApplicationReason string
	Checksum          string
	Extra             map[string]string
}

DirectDebitTerminationRequest describes a termination of an existing FPX Direct Debit mandate.

type FailedActionError

type FailedActionError struct {
	Message string
}

FailedActionError is returned for an HTTP 400 response. Message is extracted from the response body's "message" or "error" key, falling back to the raw body.

func (*FailedActionError) Error

func (e *FailedActionError) Error() string

type FlexBool

type FlexBool bool

FlexBool is a bool that decodes tolerantly from a JSON bool, number, or string ("1"/"0", "true"/"false").

func (FlexBool) Bool

func (b FlexBool) Bool() bool

Bool returns the underlying bool.

func (*FlexBool) UnmarshalJSON

func (b *FlexBool) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

type FlexString

type FlexString string

FlexString is a string that decodes tolerantly from a JSON string, number, or boolean. The gateway occasionally returns numeric fields (ids, amounts, statuses) either quoted or unquoted; FlexString normalises both to their string form.

func (FlexString) Float64

func (f FlexString) Float64() (float64, error)

Float64 parses the value as a float. It is convenient for amount fields.

func (FlexString) String

func (f FlexString) String() string

String returns the underlying string.

func (*FlexString) UnmarshalJSON

func (f *FlexString) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

type FpxBank

type FpxBank struct {
	BankName         *string   `json:"bank_name,omitempty"`
	BankDisplayName  *string   `json:"bank_display_name,omitempty"`
	BankCode         *string   `json:"bank_code,omitempty"`
	BankCodeHashed   *string   `json:"bank_code_hashed,omitempty"`
	BankAvailability *FlexBool `json:"bank_availability,omitempty"`
}

FpxBank is an FPX bank returned by FpxBanksList. Fields the API omits are nil.

type FpxDirectDebitApplication

type FpxDirectDebitApplication struct {
	PayerName            *string     `json:"payer_name,omitempty"`
	PayerIDType          *int        `json:"payer_id_type,omitempty"`
	PayerID              *string     `json:"payer_id,omitempty"`
	PayerEmail           *string     `json:"payer_email,omitempty"`
	PayerTelephoneNumber *string     `json:"payer_telephone_number,omitempty"`
	OrderNumber          *string     `json:"order_number,omitempty"`
	Amount               *FlexString `json:"amount,omitempty"`
	ApplicationType      *string     `json:"application_type,omitempty"`
	ApplicationReason    *string     `json:"application_reason,omitempty"`
	FrequencyMode        *string     `json:"frequency_mode,omitempty"`
	EffectiveDate        *string     `json:"effective_date,omitempty"`
	ExpiryDate           *string     `json:"expiry_date,omitempty"`
	URL                  *string     `json:"url,omitempty"`
}

FpxDirectDebitApplication is the result of an enrolment, maintenance, or termination request. Fields the API omits are nil.

type FpxDirectDebitMandate

type FpxDirectDebitMandate struct {
	ID                     *FlexString    `json:"id,omitempty"`
	UpdatedAt              *string        `json:"updated_at,omitempty"`
	MandateReferenceNumber *string        `json:"mandate_reference_number,omitempty"`
	OrderNumber            *string        `json:"order_number,omitempty"`
	ApplicationReason      *string        `json:"application_reason,omitempty"`
	FrequencyMode          *string        `json:"frequency_mode,omitempty"`
	FrequencyModeLabel     *string        `json:"frequency_mode_label,omitempty"`
	EffectiveDate          *string        `json:"effective_date,omitempty"`
	ExpiryDate             *string        `json:"expiry_date,omitempty"`
	Currency               *string        `json:"currency,omitempty"`
	Amount                 *FlexString    `json:"amount,omitempty"`
	PayerName              *string        `json:"payer_name,omitempty"`
	PayerID                *string        `json:"payer_id,omitempty"`
	PayerIDType            *int           `json:"payer_id_type,omitempty"`
	PayerBankAccountNumber *string        `json:"payer_bank_account_number,omitempty"`
	PayerEmail             *string        `json:"payer_email,omitempty"`
	PayerTelephoneNumber   *string        `json:"payer_telephone_number,omitempty"`
	Status                 *FlexString    `json:"status,omitempty"`
	StatusDescription      *string        `json:"status_description,omitempty"`
	ReturnURL              *string        `json:"return_url,omitempty"`
	Metadata               map[string]any `json:"metadata,omitempty"`
	Portal                 *string        `json:"portal,omitempty"`
	Merchant               map[string]any `json:"merchant,omitempty"`
}

FpxDirectDebitMandate is a mandate returned by GetFpxDirectDebit. Fields the API omits are nil.

type ManualBankTransferRequest

type ManualBankTransferRequest struct {
	PortalKey                 string
	PaymentGateway            int
	OrderNo                   string
	OrderAmount               string
	BuyerName                 string
	BuyerEmail                string
	BuyerTelNo                string
	MerchantBankName          string
	MerchantBankAccount       string
	MerchantBankAccountHolder string
	BankTransferType          string
	BankTransferNotes         string
	BankTransferDate          string // optional, "YYYY-MM-DD"; defaults to today
	ProofOfPayment            string // optional path to the proof-of-payment file
	Extra                     map[string]string
}

ManualBankTransferRequest describes a manual (offline) bank transfer to submit. PaymentGateway must be 2 (ManualTransfer). ProofOfPayment, when set, is the path to a jpeg/png/gif/pdf file.

type ManualBankTransferResult

type ManualBankTransferResult struct {
	StatusCode  int
	Success     bool
	HTMLForm    string
	FormData    map[string]string
	ReturnURL   string
	IsRedirect  bool
	RedirectURL string
	Location    string
	JSON        any
	Raw         string
}

ManualBankTransferResult is the outcome of CreateManualBankTransfer. The gateway may respond in several shapes; inspect the fields to determine which:

  • Success/HTMLForm/FormData/ReturnURL when it returns an HTML form,
  • JSON when it returns a JSON body,
  • Raw when it returns a non-JSON, non-form body,
  • IsRedirect/RedirectURL/Location when a redirect was returned but not followed (allowRedirect was false).

type NotFoundError

type NotFoundError struct{}

NotFoundError is returned for an HTTP 404 response.

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

type Option

type Option func(*Client)

Option configures a Client during construction.

func WithAPIVersion

func WithAPIVersion(version string) Option

WithAPIVersion sets the API version, "v2" (default) or "v3".

func WithBaseURL

func WithBaseURL(baseURL string) Option

WithBaseURL overrides the API base URL (must end with a trailing slash). This is primarily useful for testing or self-hosted gateways; leave it unset to use the standard Bayarcash hosts.

func WithHTTPClient

func WithHTTPClient(hc *http.Client) Option

WithHTTPClient sets a custom *http.Client. When provided, its Timeout is left untouched by WithTimeout / SetTimeout.

func WithSandbox

func WithSandbox(sandbox bool) Option

WithSandbox selects the sandbox environment when sandbox is true.

func WithSecretKey

func WithSecretKey(secretKey string) Option

WithSecretKey sets the API secret key used to sign requests and verify callbacks. The per-call secretKey argument on the checksum/verify methods takes precedence; this value is used when that argument is empty.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the request timeout. The default is 30 seconds.

type PaymentIntent

type PaymentIntent struct {
	PayerName            *string     `json:"payer_name,omitempty"`
	PayerEmail           *string     `json:"payer_email,omitempty"`
	PayerTelephoneNumber *string     `json:"payer_telephone_number,omitempty"`
	OrderNumber          *string     `json:"order_number,omitempty"`
	Amount               *FlexString `json:"amount,omitempty"`
	URL                  *string     `json:"url,omitempty"`
	Type                 *string     `json:"type,omitempty"`
	ID                   *FlexString `json:"id,omitempty"`
	Status               *FlexString `json:"status,omitempty"`
	LastAttempt          any         `json:"last_attempt,omitempty"`
	PaidAt               *string     `json:"paid_at,omitempty"`
	Currency             *string     `json:"currency,omitempty"`
	Attempts             []any       `json:"attempts,omitempty"`
}

PaymentIntent is a payment intent returned by CreatePaymentIntent / GetPaymentIntent. Fields the API omits are nil.

type PaymentIntentRequest

type PaymentIntentRequest struct {
	PortalKey string
	// PaymentChannel is one or more channel ids (e.g. []int{FPX}). Optional; if
	// empty the payer chooses on the Bayarcash page.
	PaymentChannel       []int
	OrderNumber          string
	Amount               string // string with up to 2 decimals, e.g. "10.00"
	PayerName            string
	PayerEmail           string
	PayerTelephoneNumber string
	ReturnURL            string
	CallbackURL          string
	// Metadata is echoed back by the gateway. Sent as metadata[key]=value.
	Metadata map[string]string
	Checksum string
	// Extra holds any additional fields to send verbatim.
	Extra map[string]string
}

PaymentIntentRequest describes a payment intent to create. Build it, sign it with CreatePaymentIntentChecksumValue (setting Checksum), then pass it to CreatePaymentIntent.

type Portal

type Portal struct {
	ID                                    *FlexString      `json:"id,omitempty"`
	CreatedAt                             *string          `json:"created_at,omitempty"`
	PortalKey                             *string          `json:"portal_key,omitempty"`
	PortalName                            *string          `json:"portal_name,omitempty"`
	WebsiteURL                            *string          `json:"website_url,omitempty"`
	TransactionNotificationEmail          *string          `json:"transaction_notification_email,omitempty"`
	SecondaryTransactionNotificationEmail *string          `json:"secondary_transaction_notification_email,omitempty"`
	CustomPaymentButtonText               *string          `json:"custom_payment_button_text,omitempty"`
	EnabledSmsOnSuccessfulTransaction     *int             `json:"enabled_sms_on_successful_transaction,omitempty"`
	SplitPaymentEnabled                   *FlexBool        `json:"split_payment_enabled,omitempty"`
	SplitPaymentMerchants                 []any            `json:"split_payment_merchants,omitempty"`
	PaymentChannels                       []map[string]any `json:"payment_channels,omitempty"`
	Merchant                              map[string]any   `json:"merchant,omitempty"`
	URL                                   *string          `json:"url,omitempty"`
	MerchantID                            *FlexString      `json:"merchant_id,omitempty"`
}

Portal is a portal returned by GetPortals. Fields the API omits are nil.

type RateLimitError

type RateLimitError struct {
	ResetsAt *int64
}

RateLimitError is returned for an HTTP 429 response. ResetsAt holds the value of the x-ratelimit-reset header (a unix timestamp) when present.

func (*RateLimitError) Error

func (e *RateLimitError) Error() string

type TimeoutError

type TimeoutError struct {
	Output []any
}

TimeoutError is returned by Retry when the timeout elapses before the callback succeeds.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

type Transaction

type Transaction struct {
	ID                      *FlexString    `json:"id,omitempty"`
	UpdatedAt               *string        `json:"updated_at,omitempty"`
	CreatedAt               *string        `json:"created_at,omitempty"`
	Datetime                *string        `json:"datetime,omitempty"`
	PayerName               *string        `json:"payer_name,omitempty"`
	PayerEmail              *string        `json:"payer_email,omitempty"`
	PayerTelephoneNumber    *string        `json:"payer_telephone_number,omitempty"`
	OrderNumber             *string        `json:"order_number,omitempty"`
	Currency                *string        `json:"currency,omitempty"`
	Amount                  *FlexString    `json:"amount,omitempty"`
	ExchangeReferenceNumber *string        `json:"exchange_reference_number,omitempty"`
	ExchangeTransactionID   *string        `json:"exchange_transaction_id,omitempty"`
	PayerBankName           *string        `json:"payer_bank_name,omitempty"`
	Status                  *FlexString    `json:"status,omitempty"`
	StatusDescription       *string        `json:"status_description,omitempty"`
	ReturnURL               *string        `json:"return_url,omitempty"`
	Metadata                map[string]any `json:"metadata,omitempty"`
	Payout                  map[string]any `json:"payout,omitempty"`
	PaymentGateway          map[string]any `json:"payment_gateway,omitempty"`
	Portal                  *string        `json:"portal,omitempty"`
	Merchant                map[string]any `json:"merchant,omitempty"`
	Mandate                 map[string]any `json:"mandate,omitempty"`
}

Transaction is a transaction returned by GetTransaction and the v3 transaction queries. Fields the API omits are nil.

type TransactionFilters

type TransactionFilters struct {
	OrderNumber             string
	Status                  string
	PaymentChannel          int
	ExchangeReferenceNumber string
	PayerEmail              string
}

TransactionFilters are the optional filters accepted by GetAllTransactions (v3 only). Empty fields are omitted; a PaymentChannel of 0 is omitted.

type TransactionList

type TransactionList struct {
	Data []Transaction  `json:"data"`
	Meta map[string]any `json:"meta"`
}

TransactionList is the result of GetAllTransactions: the page of transactions plus the pagination meta.

type ValidationError

type ValidationError struct {
	// Errors is the decoded JSON error body.
	Errors map[string]any
}

ValidationError is returned for an HTTP 422 response. Errors holds the decoded JSON body describing the validation failures (typically under an "error" or "errors" key).

func (*ValidationError) Error

func (e *ValidationError) Error() string

Jump to

Keyboard shortcuts

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