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)

ForumPay

Global cryptocurrency payment gateway. Supports Pay-In and Pay-Out in BTC, ETH, USDT, and other cryptocurrencies configured in your ForumPay account.
Operations: Pay-In ✓ | Pay-Out ✓ | Webhook ✓
Processing: Asynchronous - redirect user to hosted page; final status via webhook
Fields marked with * are required.

Configuration (Mozarto back office)#

FieldDescription
username *ForumPay API username
password *ForumPay API password
forumpayUserId *Your ForumPay user/payer identifier - omitting this field causes ForumPay to reject all requests with "Payer ID is required"
webhookUrl *Your HTTPS endpoint for transaction status updates
widgetTypeForumPay payment page mode. One of "0", "1", "2", "3". Defaults to "3" if not set. See Widget type reference below
allowMultiplePaymentsWhether the payment link stays active for repeat payments after the first success. Defaults to true (reusable link). Set to false to deactivate the link after the first successful payment
itemNameLabel shown to the payer on ForumPay's hosted page describing what they are buying. Omitted from the payment page when not set

Widget type reference#

widgetTypePayment page collects
"0"Payment only
"1"Billing address + payment
"2"Billing address + shipping address + payment
"3" (default)Payment + email - ForumPay collects the payer's email itself
For widgetType "0"-"2", Mozarto forwards the payer's email to ForumPay (payer_email) since the payment page does not collect it. For "3", Mozarto omits payer_email - ForumPay collects it directly on the page.

Pay-In#

POST /v1/api/mozarto/cashier
Required header: x-user-token: Bearer <user-jwt> must be sent with every Pay-In request. The value must be a valid decodable JWT - passing a plain string causes a timeout. See Authentication.

Request body#

FieldTypeDescription
pspType *stringAlways "FORUMPAY"
type *stringAlways "PAYIN"
baseamount *numberAmount as a number (e.g. 100.00)
currency *stringFiat currency (e.g. "EUR", "USD")
userId *stringYour internal user/player identifier
email *stringUser's email address
country *stringUser's country code (e.g. "DE")

Example request#

{
  "pspType": "FORUMPAY",
  "type": "PAYIN",
  "baseamount": 100.00,
  "currency": "EUR",
  "userId": "user_123",
  "email": "player@example.com",
  "country": "DE"
}

Response#

{
  "status": "success",
  "message": "Successfully",
  "isSuccess": true,
  "data": {
    "url": "https://pay.forumpay.com/invoice/abc123xyz",
    "transactionId": "69f332c3f6abfbeab46f98db",
    "transaction_status": "Pending",
    "merchantReference": "ORDER-4821",
    "amount": 100
  }
}
FieldDescription
data.urlForumPay hosted payment page - redirect the user here to select a cryptocurrency and complete payment
data.transactionIdMozarto transaction ID - use for status queries and to match the webhook
data.transaction_statusAlways "Pending" on creation
data.merchantReferenceThe merchant reference from the request - empty string if not set
data.amountThe requested fiat amount as a number
The raw fields returned by ForumPay's payment-link creation (including url) are merged into data alongside the Mozarto fields above.
Open data.url in the user's browser. The user selects their cryptocurrency and completes payment on ForumPay's hosted page.

Pay-Out#

POST /v1/api/mozarto/cashier
Required header: x-user-token: Bearer <user-jwt> must be sent with every Pay-Out request. The value must be a valid decodable JWT. See Authentication.

Request body#

FieldTypeDescription
pspType *stringAlways "FORUMPAY"
type *stringAlways "PAYOUT"
baseamount *numberPay-Out amount as a number (e.g. 200.00)
currency *stringFiat currency the amount is denominated in
userId *stringYour internal user/player identifier
email *stringUser's email address
country *stringUser's country code
preferredCrypto *stringCryptocurrency to send - e.g. "BTC", "ETH", "USDT", "LTC"
walletAddress *stringDestination wallet address for the chosen cryptocurrency

Example request#

{
  "pspType": "FORUMPAY",
  "type": "PAYOUT",
  "baseamount": 200.00,
  "currency": "EUR",
  "userId": "user_123",
  "email": "player@example.com",
  "country": "DE",
  "preferredCrypto": "BTC",
  "walletAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
}

Response#

{
  "status": "success",
  "message": "Transaction is on hold",
  "isSuccess": true,
  "data": {
    "invoice_currency": "EUR",
    "invoice_amount": "10.00",
    "currency": "BTC",
    "payment_source": "cash",
    "wait_time": "20 minutes",
    "network_processing_fee": "0.00000966",
    "rate": "65419.3380",
    "amount_exchange": "0.00015286",
    "amount": 10,
    "fast_transaction_fee": "0.00002066",
    "fast_transaction_fee_currency": "BTC/kB",
    "payment_id": "badd0b52-110f-4be2-af64-59d7645796af",
    "reference_no": "69f332c3f6abfbeab46f98db",
    "address": "btc-1eda64a85da94d71a2ac5ed84e929553",
    "access_token": "<forumpay-access-token>",
    "transactionId": "69f332c3f6abfbeab46f98db",
    "transaction_status": "On Hold",
    "merchantReference": ""
  }
}
FieldDescription
data.transactionIdMozarto transaction ID - use for status queries
data.payment_idForumPay internal payment identifier
data.reference_noForumPay reference number - matches transactionId
data.invoice_currencyThe fiat currency of the original request
data.invoice_amountThe fiat amount as a string
data.currencyThe cryptocurrency being sent (e.g. "BTC")
data.rateExchange rate at time of transaction creation
data.amount_exchangeEquivalent crypto amount to be transferred
data.network_processing_feeBlockchain network fee in crypto
data.fast_transaction_feeOptional fast transaction fee
data.wait_timeEstimated processing time
data.addressForumPay internal payout address reference
data.access_tokenForumPay session token - do not expose to end users
data.transaction_statusAlways "On Hold" on creation - the payout awaits manual approval in the Mozarto back office before ForumPay processes the transfer
data.transactionIdMozarto transaction ID - use for status queries and to match the webhook
data.merchantReferenceThe merchant reference from the request - empty string if not set
data.amountThe requested payout amount (fiat) as a number
"Transaction is on hold": A message of "Transaction is on hold" with isSuccess: true means the payout was created successfully but requires manual approval in the Mozarto back office before ForumPay processes the transfer. Do not treat this as a failure. Show the user a "pending approval" message and wait for the webhook to deliver the final outcome (SUCCESS or REJECTED).

Webhook#

Mozarto calls your webhookUrl when the transaction reaches a final state - ForumPay reports the payment as confirmed or cancelled, and Mozarto then forwards a normalized notification to you. Pending states are acknowledged but not forwarded.

Payload example#

{
  "transaction_id": "69f332c3f6abfbeab46f98db",
  "psp_transaction_id": "69f332c3f6abfbeab46f98db",
  "user_id": "000000000000000000000001",
  "method": "FORUMPAY_PAYIN",
  "status": "confirmed",
  "transaction_status": "Approved",
  "message": "Crypto payment confirmed and successfully processed",
  "currency": "BTC",
  "confirmed": true,
  "invoice_currency": "EUR",
  "merchantReference": "ORDER-4821",
  "amount": 100
}
FieldDescription
transaction_idMozarto transaction ID - matches data.transactionId from the Pay-In/Pay-Out response
psp_transaction_idForumPay reference number - matches transaction_id
user_idThe user ID from the original transaction
methodTransaction method - "FORUMPAY_PAYIN" or "FORUMPAY_PAYOUT". Use this to distinguish Pay-In from Pay-Out
statusRaw ForumPay state - "confirmed" or "cancelled". Do not use for business logic
transaction_statusNormalized Mozarto status - "Approved" or "Declined". Use this for all business logic
messageHuman-readable description of the outcome
currencyThe cryptocurrency the payment settled in (e.g. "BTC")
confirmedBoolean - whether ForumPay confirmed the on-chain payment
invoice_currencyThe fiat currency of the original request (e.g. "EUR")
merchantReferenceThe merchant reference passed in the original request - empty string if not set
amountTransaction amount as a number

Error webhook#

If the transaction fails, Mozarto forwards an error notification instead. It carries status: "error", transaction_status: "Failed", currency: "error", confirmed: false, and an additional error object with the raw ForumPay failure details:
{
  "transaction_id": "69f332c3f6abfbeab46f98db",
  "psp_transaction_id": "69f332c3f6abfbeab46f98db",
  "user_id": "000000000000000000000001",
  "method": "FORUMPAY_PAYIN",
  "status": "error",
  "transaction_status": "Failed",
  "message": "Transaction failed due to an internal error",
  "currency": "error",
  "confirmed": false,
  "invoice_currency": "EUR",
  "error": { "err": "..." },
  "merchantReference": "ORDER-4821",
  "amount": 100
}
Note on duplicates: ForumPay may deliver multiple webhook callbacks for the same transaction. Implement idempotency on your side - check the current state of the transaction before applying any changes. See Webhook Setup.

Error codes#

ForumPay transport failures are mapped to normalized Mozarto errorCode values. Use errorCode for programmatic handling rather than parsing raw data.err strings.
Mozarto errorCodePSP raw signalWhen
PSP_NOT_CONFIGUREDMissing credentials in Mozarto back officeusername, password, or forumpayUserId not set for this brand
INVALID_PSP_CREDENTIALSHTTP 401 / 403, or body contains "Unauthorized" or "Invalid credentials"API credentials are wrong or expired
PSP_NOT_CONFIGUREDBody contains "Payer ID is required"forumpayUserId is missing from the ForumPay configuration
PSP_TIMEOUTHTTP 408, or response body contains "timeout"ForumPay did not respond in time - safe to retry
PSP_UNAVAILABLEHTTP 5xxForumPay service error - safe to retry with backoff
PSP_RATE_LIMITEDHTTP 429Too many requests - retry after a delay
UNKNOWN_PSP_ERRORHTTP 200 with data.err or data.err_code setForumPay returned a business-level rejection (e.g. invalid wallet address, unsupported currency pair) - check data.err and data.err_code for the raw ForumPay reason
UNKNOWN_PSP_ERRORAny other unrecognised responseFallback - check data for the raw ForumPay response and contact support if it persists
Business rejections: ForumPay may return HTTP 200 with data.err and data.err_code fields set when a transaction is rejected at the application layer (for example, an unsupported cryptocurrency or an invalid wallet address). These produce UNKNOWN_PSP_ERROR because the HTTP status is not available at that boundary. Inspect data.err_code for the ForumPay-specific reason.
For the full list of errorCode values and retryability guidance, see Errors.
Modified at 2026-09-01 13:16:47
Previous
Flexepin
Next
Gigadat
Built with