1. 7. Payment Providers (PSPs)
Mozarto - The Payments Orchestration Platform
  • 1. Introduction
  • 2. Quick Start
  • 3. Authentication
  • 4. Webhook Setup
  • 5. Errors
  • 6. Redirect flow
    • Pay-In Flow
    • Pay-Out Flow
  • 7. Payment Providers (PSPs)
    • Overview
    • Brite
    • CashLib
    • Cleo
    • Contiant
    • emerchantpay
    • Flexepin
    • ForumPay
    • Gigadat
    • Neosurf
    • OFApay
    • PayModum
    • PayOne
    • PawaPay
    • Trust Payments
    • Worldpay
  • 8. Redirect Flow APIs
    • Redirect Flow APIs - overview
    • Pay-In
      • Brite
      • CashLib
      • Cleo
      • Contiant
      • emerchantpay
      • Flexepin
      • Forumpay
      • Gigadat
      • Neosurf
      • OFApay
      • PayOne
      • PawaPay
      • Trust Payments
      • WorldPay
    • Pay-Out
      • Cleo
      • Forumpay
      • Gigadat withdraw ACH
      • Gigadat withdraw ETO
      • PawaPay
      • PayOne
      • Trust Payments
  • Webhook
    • ForumPay status webhook
    • PayOne status webhook
  • Schemas
    • TransactionData
  1. 7. Payment Providers (PSPs)

OFApay

Asian payment aggregator covering e-wallets, QR, and bank transfers (Philippines PHP, Korea KRW). The payer pays from their e-wallet (GCash, Maya, GrabPay), scans a QR (QRPH), or receives a bank payout. Deposits are processed through OFApay's hosted payment page; payouts are sent directly to the recipient's wallet/bank. Supports Pay-In and Pay-Out.
Operations: Pay-In ✓ | Pay-Out ✓ | Webhook ✓
Processing: Asynchronous - Pay-In redirects the payer to OFApay's hosted payment page (or renders a QR); final status for both flows arrives via webhook
Payment type: E-wallet / QR / Bank transfer
Account-per-method: OFApay is configured as one account per payment method. Each account carries its own scode (MID) and signature key, tagged with the method it serves (GCash, Maya, …). The paymentMethod you send on the cashier call selects which account is used. The currency and routing (paytype) are fixed per method and derived server-side - you do not send paytype.
Currency is fixed per method: GCash / Maya / GrabPay / QRPH → PHP, Bank Payouts → KRW.
Fields marked with * are required.

Payment methods#

Method (paymentMethod)LabelCurrencyCountryPay-InPay-Out
GCASHGCashPHPPHL✓✓
MAYAMayaPHPPHL✓✓
GRABPAYGrabPayPHPPHL✓✓
QRPHQRPHPHPPHL✓✓
BANK_KRWBank PayoutsKRWKOR-✓

Configuration (Mozarto back office)#

One configuration is created per payment method.
FieldDescription
accountName *Display name for this account
paymentMethod *The OFApay method this account serves (GCash, Maya, GrabPay, QRPH, Bank Payouts)
scode *OFApay Merchant ID (MID). Provided by OFApay per method
apiKey *OFApay signature key used to sign requests and verify callbacks (MD5). Stored per brand, encrypted at rest, and masked in the back office
siteUrlDefault return URL - OFApay redirects the payer here after completing a Pay-In on the hosted page. Used when the transaction does not send its own siteUrl
webhookUrl *Your HTTPS endpoint for transaction status updates
commentOptional free-text note for this configuration

Pay-In#

POST /v1/api/mozarto/cashier
The cashier call does not move funds directly. It creates a transaction and returns a paymentUrl (OFApay's hosted payment page). Redirect the payer to that URL, where they confirm the payment in their e-wallet or scan the QR. The final status arrives later via webhook.
Payer identity comes from the user token. firstName, lastName, and email are taken from the authenticated user (x-user-token) and must not be sent in the body.

Request body#

FieldTypeDescription
pspType *stringAlways "OFAPAY"
type *stringAlways "PAYIN"
paymentMethod *stringSelects the OFApay account/method. Pay-In values: "GCASH" (GCash), "MAYA" (Maya), "GRABPAY" (GrabPay), "QRPH" (QRPH). "BANK_KRW" (Bank Payouts) is Pay-Out only
baseamount *numberAmount as a number (e.g. 200)
currency *stringCurrency code. Must match the method's fixed currency (e.g. "PHP")
country *stringISO 3166-1 alpha-3 country code (e.g. "PHL")
phone *stringPayer's phone number (digits only, e.g. 09171234567)
banknostringBank/channel code for methods that route directly to a bank. Optional - depends on the method
accountnostringPayer's account number
accountnamestringPayer's name
addressstringPayer's address
citystringPayer's city
streetstringPayer's street
zipCodestringPayer's postal code (sent to OFApay as zip_code)
merchantReferencestringYour reference, echoed back in the response and webhook
siteUrlstringReturn URL the payer lands on after payment. Overrides the configured siteUrl for this transaction; falls back to the configured value when omitted
webhookUrlstringHTTPS endpoint for the status webhook. Overrides the configured webhookUrl for this transaction; falls back to the configured value when omitted

Example request#

{
  "pspType": "OFAPAY",
  "type": "PAYIN",
  "paymentMethod": "GCASH",
  "baseamount": 200,
  "currency": "PHP",
  "country": "PHL",
  "phone": "09171234567",
  "merchantReference": "ORDER-4821"
}

Response#

{
  "isSuccess": true,
  "data": {
    "merchantReference": "ORDER-4821",
    "amount": 200,
    "transaction_status": "Pending",
    "paymentUrl": "https://www.jzc899.com/pay/deposit.aspx?u=...&v=2.0",
    "qrUrl": "",
    "qrcode": "",
    "floatingamount": ""
  },
  "statusCode": 200
}
FieldTypeDescription
isSuccessbooleantrue when the transaction was set up successfully
paymentUrlstringOFApay hosted payment page URL - redirect the payer here
qrUrlstringQR code image URL, when the channel returns one (e.g. QRPH)
qrcodestringQR code payload/key, when the channel returns one
floatingamountstringAdjusted amount the payer must pay, when the channel uses floating amounts - otherwise empty
merchantReferencestringThe merchant reference passed in the request - empty string if not set
amountnumberTransaction amount as a number
transaction_statusstringAlways "Pending" at this point. The final outcome arrives by webhook
statusCodenumberHTTP status code (200 on success)

Pay-Out#

POST /v1/api/mozarto/cashier
Pay-Out is a direct API call - no hosted page and no paymentUrl. Mozarto sends the payout to the recipient's wallet or bank account. The final status arrives via webhook.

Request body#

FieldTypeDescription
pspType *stringAlways "OFAPAY"
type *stringAlways "PAYOUT"
paymentMethod *stringSelects the OFApay account/method: "GCASH" (GCash), "MAYA" (Maya), "GRABPAY" (GrabPay), "QRPH" (QRPH), "BANK_KRW" (Bank Payouts)
baseamount *numberAmount as a number (e.g. 200)
currency *stringCurrency code. Must match the method's fixed currency (e.g. "PHP", "KRW")
phone *stringRecipient's wallet/phone number (digits only)
accountno *stringRecipient's bank/wallet account number
accountname *stringRecipient's account holder name
bankname *stringBank name from OFApay's bank list
bankno *stringBank/channel code from OFApay's bank list identifying the recipient's bank or wallet
branchname *stringBeneficiary bank branch name
branchcode *stringBeneficiary bank branch code
banknumstringIFSC code - required for INR payouts
taxnostringTaxpayer identification number
postalcodestringRecipient postal code
provincestringRecipient province
citystringRecipient city
genderstringM or F
country *stringRecipient country - ISO 3166-1 alpha-2 (e.g. "JP"). Forwarded to OFApay and matched against the account's Processing Scope
addressstringRecipient address
idTypestringCredential type - 1 = ID, 2 = Passport
idNumberstringCredential number
issueDatestringCredential issue date (YYYY-MM-DD)
expireDatestringCredential expiry date (YYYY-MM-DD)
areastringCountry calling code, digits only (e.g. "81")
nationalitystringRecipient nationality (2-letter, e.g. "JP")
merchantReferencestringYour reference, echoed back in the response and webhook
webhookUrlstringHTTPS endpoint for the status webhook. Overrides the configured webhookUrl for this transaction; falls back to the configured value when omitted
Payer name (surName/givName at OFApay) is resolved from the X-User-token (last/first name), so it is not sent in the request body.

Example request#

{
  "pspType": "OFAPAY",
  "type": "PAYOUT",
  "paymentMethod": "GCASH",
  "baseamount": 200,
  "currency": "PHP",
  "country": "PH",
  "phone": "09171234567",
  "accountno": "09171234567",
  "accountname": "Ban Lu",
  "bankname": "GCash",
  "bankno": "600",
  "branchname": "Main Branch",
  "branchcode": "001",
  "merchantReference": "PAYOUT-7723"
}

Response#

{
  "isSuccess": true,
  "data": {
    "merchantReference": "PAYOUT-7723",
    "amount": 200,
    "transaction_status": "Processing"
  },
  "statusCode": 200
}
FieldTypeDescription
isSuccessbooleantrue when the transaction was set up successfully
merchantReferencestringThe merchant reference passed in the request - empty string if not set
amountnumberTransaction amount as a number
transaction_statusstringAlways "Processing" at this point. The final outcome arrives by webhook
statusCodenumberHTTP status code (200 on success)

Webhook#

Mozarto calls your webhookUrl when the transaction reaches a final state. OFApay notifies Mozarto on its own callback URL first; Mozarto then forwards a normalized notification to you. The payload is identical for Pay-In and Pay-Out - it carries no flow indicator. Match transaction_id against the cashier call to distinguish them. Non-final statuses (e.g. still processing) are acknowledged but not forwarded.

Payload example#

{
  "transaction_id": "64a1f2b3c4d5e6f7a8b9c0d1",
  "psp_transaction_id": "9f3c1a20-6c7e-4d0e-b2b1-8a1f2c3d4e5f",
  "user_id": "000000000000000000000001",
  "status": "success",
  "transaction_status": "Approved",
  "amount": 200,
  "currency": "PHP",
  "merchantReference": "ORDER-4821"
}
FieldDescription
transaction_idMozarto transaction ID for this transaction. Match it against your stored merchantReference
psp_transaction_idOFApay order ID (orderid) generated by Mozarto for this transaction
user_idThe user ID from the original transaction
statusRaw settlement result - success or failed. Do not use for business logic
transaction_statusNormalized Mozarto status - "Approved" or "Failed". Use this for all business logic
amountTransaction amount as a number
currencyTransaction currency
merchantReferenceThe merchant reference passed in the original request - empty string if not set

Status values#

The webhook forwards only the normalized Mozarto statuses:
Settlement (status)Normalized (transaction_status)Meaning
successApprovedTransaction completed successfully
failedFailedTransaction failed
pending-Still processing - acknowledged only, not forwarded

Payer-info webhook (Pay-In)#

For some channels OFApay does not know the payer's wallet details at request time. When the payer completes the payment, OFApay calls Mozarto's payer-info endpoint with the payer's payeraccount and payername; Mozarto stores these against the transaction. This is internal to Mozarto and is not forwarded to your webhook.

Error codes#

The cashier call returns an error when the transaction cannot be set up. Payment declines are reported later through the webhook with transaction_status: "Failed", not on this call.
HTTP statusResponseWhen
400message: "Missing required field: paymentMethod"paymentMethod was not sent
400message: "Unsupported OFApay payment method: <value>"paymentMethod is not a recognized OFApay method
400message: "OFApay <method> does not support Pay In"The selected method does not support the requested direction (e.g. Bank Payouts is Pay-Out only)
400message: "PSP Configuration not found. Please check you psp Configuration"The OFApay account for this method is missing its scode or apiKey in the back office
400message carries OFApay's respmsg / msg (e.g. amount over limit, incorrect parameter)OFApay rejected the deposit or withdrawal request
For the full list of errorCode values and retryability guidance, see Errors.
Modified at 2026-09-14 11:34:13
Previous
Neosurf
Next
PayModum
Built with