RECURSOS PARA DESARROLLADORES

Desarrollo de API

Referencia API, ejemplos de servidor y móvil, retornos y notificaciones en una sola guía. PHP, Node.js, Python, C#, Java, iOS Swift y Android Kotlin admiten ON_SITE y HPP.

REST API · INTERFAZ DE PAGO

Un pedido. ON_SITE o HPP.

Crea y vincula el pedido en tu servidor; después elige la presentación. Ambos modos conservan order_id.

ConsultaRetornos síncronos HPP y notificaciones asíncronas ON_SITE/HPP, con código PHP, Node.js, Python, C# y Java.

ON_SITE

Diálogo de pago en tu tienda

Muestra importe, dirección, red y QR en un diálogo propio. Tu servidor consulta y devuelve una vista segura.

Ver HTML y PHP →
HPP

Redirigir al pago MochiPay

Redirige a payment_url y verifica retorno o notificación con Query Order autenticado.

Ver redirección PHP →

Fragmentos de checkout.php y los auxiliares de PHP Demo 1.1.4 (PHP 7.0–8.4). Crea primero con order.php para obtener ambos enlaces. En producción, carga el pedido autorizado desde la sesión/base de datos y finalízalo mediante una transacción idempotente.

Redirigir tras verificar en el servidor

HPP · PHP

Validate the stored order binding and destination, then send the Location header before any page output.

checkout.php · HPP branch
// checkout.php: after loading the saved attempt and
// verifying its token, order binding and payment URL.
// $payment is the authenticated Query Order response.
if ($mode === 'HPP') {
    header('Location: ' . $payment['payment_url'], true, 303);
    exit; // Send the header before any HTML output.
}
// Verify the notification/return server-side before fulfillment.

The complete file loads the saved attempt and validates its token, authenticated query and expected payment_url before this branch.

Mostrar el diálogo en tu página

ON_SITE · PHP + HTML

Include the local dialog assets in your checkout HTML. The browser talks to your local poll endpoint; it never signs requests or receives API credentials.

checkout.php · local dialog assets
// checkout.php: use the SAME saved reference/token.
$pollUrl = 'order.php?' . http_build_query([
    'view' => $reference, 'token' => $token, 'poll' => 1
], '', '&', PHP_QUERY_RFC3986);
$completeUrl = 'callback.php?' . http_build_query([
    'mode' => 'return', 'merchant_order_id' => $reference
], '', '&', PHP_QUERY_RFC3986);
$config = json_encode([
    'poll' => $pollUrl, 'complete' => $completeUrl
], JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
?>
<!-- Inside your own checkout page: -->
<link rel="stylesheet" href="portable/onsite.css">
<button id="reopen" type="button">Open payment dialog</button>
<script>window.MochiPayConfig = <?php echo $config; ?>;</script>
<script src="portable/qrcode.min.js"></script>
<script src="portable/onsite.js"></script>

onsite.js opens the dialog over your existing page. Closing it leaves checkout visible; the Open payment dialog button reopens the same payment.

Tu servidor verifica el pedido

Authorize the saved reference/token, query by the stored MochiPay order_id, and compare the original amount/currency, asset/network, address and exact payable amount. Return only a safe payment view with decimal strings.

order.php · local polling endpoint
// order.php?view=...&token=...&poll=1 (server-side)
// The demo has already authorized the saved attempt/token.
$response = mochipay_query_order(
    'order_id', $record['snapshot']['order_id']
);
if (!$response['ok'] || !mochipay_bound($record, $response['data'])) {
    http_response_code(403);
    exit;
}
// Also check the expected received amount before accepting PAID.
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
echo json_encode([
    'success' => true,
    'data' => MochiPayPortable::view($response['data'])
]); // Safe view: decimal strings; no credentials/customer fields.

The full demo additionally verifies the received amount for PAID. callback.php verifies notifications and browser returns. A screenshot, redirect or browser flag is never proof of payment.

Autenticación

Every API request must include the merchant API key and a Base64-encoded HMAC-SHA256 signature.

CabeceraobligatorioDescripción
X-Mochi-KeySíYour merchant API key.
X-Mochi-SignatureSíBase64-encoded HMAC-SHA256 signature.
Content-TypePOST requestsapplication/json
Keep your API secret on the server. Never expose it in browser JavaScript, mobile applications or public source code.

Firma

For Create Order, sign the exact raw JSON body. For Query Order, sign the raw query string without the leading ?.

SIGNATURE FORMULA
Base64(HMAC-SHA256(UTF8(signing_text), UTF8(api_secret)))

Monedas admitidas

The order currency prices the purchase. The payment method selects the cryptocurrency and blockchain network used to pay.

MONEDAS DE PEDIDOS

28 supported fiat currencies

Use one of these exact ISO codes in the currency Campo.

USDEURGBPCAD AUDNZDJPYCNY HKDSGDCHFSEK NOKDKKPLNCZK HUFAEDSARINR IDRTHBMYRPHP KRWBRLMXNZAR
CRYPTO ORDER CURRENCIES

Precios en criptomonedas

Orders may also be priced directly in these cryptocurrencies.

USDTUSDCBTCETHSOL
MÉTODOS DE PAGO

Supported cryptocurrency and network combinations

Send one of these exact values in the payment_method Campo.

USDT_TRC20USDT on TRON
USDC_ERC20USDC on Ethereum
BTC_BITCOINNative BTC on Bitcoin
ETH_ERC20Native ETH on Ethereum
SOL_SOLANANative SOL on Solana
Regla de conversión: If the order currency and payment asset are the same, MochiPay uses a rate of 1 without conversion. Otherwise, the stored exchange rate and merchant markup are applied when the order is created. View current reference exchange rates →
Valor del pedidoMétodo de pagoResultado
49.90 USDUSDT_TRC20Uses the stored USD → USDT rate and merchant markup.
100 EURBTC_BITCOINUses the stored EUR → BTC rate and merchant markup.
25 USDCUSDC_ERC20No conversion. The exchange rate is 1.

Crear pedido

Create a payment order with a hosted payment URL and the payment instructions needed for an on-site interface.

POST https://mochi.bz/api/v1/orders/create

Parámetros de solicitud

Order currency and payment method are different concepts. amountycurrency define the merchant's original order value. payment_method defines the cryptocurrency and blockchain network used by the customer to pay. For example, 49.90 USD con USDT_TRC20 means that a USD-denominated order is paid with the calculated amount of USDT on the TRON network.
ParámetroobligatorioTipo / longitudDescripción
merchant_order_idSístring · 1–100Your order reference. Without request_id, each successful creation receives a new globally unique MochiPay order_id. With request_id, a retry reuses its original order.
amountSídecimal(28,8)Positive original order amount. Fiat normally uses 2 decimal places; supported cryptocurrencies may use up to 8.
currencySístring · 1–20Original order currency code. It may be fiat, such as USD o EUR, or cryptocurrency, such as USDT o USDC.
payment_methodSíasset ≤20 + network ≤30Payment cryptocurrency and blockchain network in ASSET_NETWORK format, such as USDT_TRC20 o USDC_ERC20.
unique_amount_directionNoUP o DOWNDirection used for the small unique amount adjustment. Defaults to UP.
product_typeNoPHYSICAL o DIGITAL_SERVICEOrder type displayed at checkout. Defaults to DIGITAL_SERVICE. Shipping fields remain optional for both types.
descriptionNostring · 0–500Human-readable order description.
product_infoNoJSON/string · nvarchar(max)Product, cart or custom metadata. The complete HTTP request body must not exceed 65,536 bytes.
customer_emailNostring · 0–255Customer email address. When supplied, it must be a valid email address.
customer_phoneNostring · 0–50Customer telephone number.
first_nameNostring · 0–100Customer first name.
last_nameNostring · 0–100Customer last name.
companyNostring · 0–200Customer company or organization name.
countryNostring · 0–100Customer country or region.
stateNostring · 0–100Customer state, province or region.
cityNostring · 0–100Customer city.
address1Nostring · 0–500Primary customer address line.
address2Nostring · 0–500Additional customer address line.
postal_codeNostring · 0–30Customer postal or ZIP code.
request_idNostring · 1–64Optional retry key, scoped to your merchant. Sign it with the JSON body. Reuse the same key and payload after a timeout. See request deduplication.
notify_urlNostring · 0–1000Absoluto http:// o https:// asynchronous server notification URL. Only public destinations are allowed; localhost, private/reserved IPs and redirects are blocked.
redirect_urlNostring · 0–1000Absolute customer return URL used after a successful payment.
customer_ipNoIPv4/IPv6 · 0–45Customer IP supplied by the merchant. MochiPay also records the API request IP separately.

Ejemplo de solicitud

JSON
{
  "merchant_order_id": "ORDER-20260919-001",
  "amount": 49.90,
  "currency": "USD",
  "payment_method": "USDT_TRC20",
  "unique_amount_direction": "UP",
  "product_type": "DIGITAL_SERVICE",
  "description": "MochiPay order",
  "customer_email": "customer@example.com",
  "redirect_url": "https://merchant.example.com/payment/return"
}
C# · CREATE ORDER
string baseUrl = "https://mochi.bz";
string body = @"{
  ""merchant_order_id"": ""ORDER-20260920-001"",
  ""amount"": 49.90,
  ""currency"": ""USD"",
  ""payment_method"": ""USDT_TRC20"",
  ""unique_amount_direction"": ""UP"",
  ""product_type"": ""DIGITAL_SERVICE"",
  ""description"": ""Example order"",
  ""notify_url"": ""https://merchant.example.com/mochipay/notify"",
  ""redirect_url"": ""https://merchant.example.com/payment/return""
}";

string signature;
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret)))
{
    signature = Convert.ToBase64String(
        hmac.ComputeHash(Encoding.UTF8.GetBytes(body)));
}

using (var client = new HttpClient())
using (var request = new HttpRequestMessage(
    HttpMethod.Post, baseUrl + "/api/v1/orders/create"))
{
    request.Headers.Add("X-Mochi-Key", apiKey);
    request.Headers.Add("X-Mochi-Signature", signature);
    request.Content = new StringContent(body, Encoding.UTF8, "application/json");
    HttpResponseMessage response = await client.SendAsync(request);
    string json = await response.Content.ReadAsStringAsync();
}
PHP 7.0–8.4 · CREATE ORDER
<?php
$baseUrl = 'https://mochi.bz';
$apiKey = 'YOUR_API_KEY';
$apiSecret = 'YOUR_API_SECRET';

$payload = [
    'merchant_order_id' => 'ORDER-20260920-001',
    'amount' => '49.90',
    'currency' => 'USD',
    'payment_method' => 'USDT_TRC20',
    'unique_amount_direction' => 'UP',
    'product_type' => 'DIGITAL_SERVICE',
    'description' => 'Example order',
    'notify_url' => 'https://merchant.example.com/mochipay/notify',
    'redirect_url' => 'https://merchant.example.com/payment/return'
];

$body = json_encode($payload, JSON_UNESCAPED_SLASHES);
$signature = base64_encode(
    hash_hmac('sha256', $body, $apiSecret, true)
);

$ch = curl_init($baseUrl . '/api/v1/orders/create');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Mochi-Key: ' . $apiKey,
        'X-Mochi-Signature: ' . $signature
    ],
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_TIMEOUT => 30
]);

$json = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);

if ($json === false) {
    throw new RuntimeException($error);
}

// Preserve decimal JSON numbers as text before decoding.
$json = preg_replace(
    '/("(?:amount|base_pay_amount|pay_amount|received_amount|exchange_rate|rate_markup_percent|unique_amount_delta)"\s*:\s*)(-?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)(?=\s*[,}])/',
    '$1"$2"', $json
);
$result = json_decode($json, true);
if ($httpCode < 200 || $httpCode >= 300 || empty($result['success'])) {
    throw new RuntimeException('MochiPay request failed. Review before retrying creation.');
}
?>

Respuesta correcta

CampoTipo / longitudDescripción
successbooleanTrue when creation succeeds.
order_idstring · 32MochiPay system identifier. Store it with your local order.
merchant_order_idstring · ≤100Your original merchant reference.
product_typestring · ≤20PHYSICAL or DIGITAL_SERVICE.
statusstring · ≤20Current payment status.
amountdecimal(28,8)Original order amount; preserve decimal precision.
currencystring · ≤20Original pricing currency.
base_pay_amountdecimal(28,8)Converted amount before the unique adjustment.
unique_amount_deltadecimal(28,8)Signed matching adjustment.
unique_amount_directionstring · ≤10UP or DOWN.
pay_amountdecimal(28,8)Exact chain amount to display and send. Do not round.
payment_methodstringSelected asset/network, e.g. USDT_TRC20.
payment_addressstring · ≤255Receiving address for this payment and network.
payment_urlstring · URLHPP URL. On-site uses the same order instructions.
expires_atdatetimeExpiration in yyyy-MM-dd HH:mm:ss format.
HTTP 200 · JSON
{
  "success": true,
  "order_id": "41ad45477bd444f3bd89f0bab7f571bb",
  "merchant_order_id": "ORDER-20261003-001",
  "product_type": "DIGITAL_SERVICE",
  "status": "WAITING_PAYMENT",
  "amount": 49.90,
  "currency": "USD",
  "base_pay_amount": 49.90,
  "unique_amount_delta": 0.001,
  "unique_amount_direction": "UP",
  "pay_amount": 49.901,
  "payment_method": "USDT_TRC20",
  "payment_address": "TExampleReceivingAddressForIllustrationOnly",
  "payment_url": "https://mochi.bz/pay/41ad45477bd444f3bd89f0bab7f571bb",
  "expires_at": "2026-10-03 15:30:00"
}

Consultar pedido

Retrieve an order owned by the authenticated merchant using exactly one order identifier.

GET https://mochi.bz/api/v1/orders/query
Parámetro de consultaobligatorioTipo / longitudDescripción
order_idOne of twostring · 32MochiPay order identifier.
merchant_order_idOne of twostring · 1–100Your merchant order identifier. If it was reused, the newest matching order is returned.
Usar order_id once stored. After an uncertain Create response, query the same unique merchant reference before deciding what happened; repeated Create requests are not guaranteed to be idempotent. Send only one identifier. Sign the exact raw query string, for example merchant_order_id=ORDER-20260919-001.

Ejemplos de consulta

C# · QUERY ORDER
string baseUrl = "https://mochi.bz";
string query = "merchant_order_id=ORDER-20260919-001";

using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret)))
{
    string signature = Convert.ToBase64String(
        hmac.ComputeHash(Encoding.UTF8.GetBytes(query)));

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("X-Mochi-Key", apiKey);
        client.DefaultRequestHeaders.Add("X-Mochi-Signature", signature);
        string json = await client.GetStringAsync(
            baseUrl + "/api/v1/orders/query?" + query);
    }
}
PHP 7.0–8.4 · QUERY ORDER
<?php
$baseUrl = 'https://mochi.bz';
$apiKey = 'YOUR_API_KEY';
$apiSecret = 'YOUR_API_SECRET';
$query = http_build_query(
    ['merchant_order_id' => 'ORDER-20260919-001'],
    '',
    '&',
    PHP_QUERY_RFC3986
);
$signature = base64_encode(
    hash_hmac('sha256', $query, $apiSecret, true)
);

$ch = curl_init($baseUrl . '/api/v1/orders/query?' . $query);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-Mochi-Key: ' . $apiKey,
        'X-Mochi-Signature: ' . $signature
    ],
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_TIMEOUT => 30
]);

$json = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);

if ($json === false) {
    throw new RuntimeException($error);
}

// Preserve decimal JSON numbers as text before decoding.
$json = preg_replace(
    '/("(?:amount|base_pay_amount|pay_amount|received_amount|exchange_rate|rate_markup_percent|unique_amount_delta)"\s*:\s*)(-?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)(?=\s*[,}])/',
    '$1"$2"', $json
);
$result = json_decode($json, true);
if ($httpCode < 200 || $httpCode >= 300 || empty($result['success'])) {
    throw new RuntimeException('MochiPay request failed. Review before retrying creation.');
}
?>

Campos de respuesta correcta

The query returns wallet_typeynetwork separately; Create Order returns their combined payment_method. Compare them with the method saved on your local order. Return only necessary payment fields to the customer browser.

CampoTipo / longitudDescripción
order_idstring · 32MochiPay order identifier.
merchant_order_idstring · ≤100Your merchant order identifier.
sourcestring · ≤20Order source, such as API.
descriptionstring · ≤500Order description.
product_typestring · ≤20PHYSICAL o DIGITAL_SERVICE.
product_infoJSON/string/nullProduct or cart information supplied when the order was created.
statusstring · ≤20Overall order payment status.
merchant_statusstring · ≤50Merchant-facing order status.
amountdecimal(28,8)Original order amount.
currencystring · ≤20Original order currency, such as USD, EUR, USDT o USDC.
base_pay_amountdecimal(28,8)Converted payment amount before the unique matching adjustment.
unique_amount_deltadecimal(28,8)Small signed amount added to or subtracted from the base amount.
unique_amount_directionstring · ≤10UP o DOWN.
pay_amountdecimal(28,8)Exact cryptocurrency amount the customer must pay.
received_amountdecimal(28,8)Cryptocurrency amount received so far.
exchange_ratedecimal(38,18)Exchange-rate snapshot used when the order was created.
rate_markup_percentdecimal(9,4)Merchant rate markup snapshot used for the order.
wallet_typestring · ≤20Activo de pago: USDT, USDC, BTC, ETH o SOL.
networkstring · ≤30Blockchain network, such as TRC20 o ERC20.
payment_addressstring · ≤255Merchant receiving address selected for this order.
tx_hashstring/null · ≤255Detected customer payment transaction hash.
confirmationsintegerCurrent blockchain confirmation count.
customer_email … postal_codestring/nullOptional customer and shipping fields supplied at order creation.
payment_urlstring · URLHPP checkout URL; on-site integrations query the same order for status and payment instructions.
expires_atdatetimeOrder expiration time.
paid_atdatetime/nullPayment completion time.
created_atdatetimeOrder creation time.
updated_atdatetimeLast order update time.

Ejemplos de código

PHP, Node.js, Python, C# / .NET Framework, Java, iOS Swift y Android Kotlin. Un pago guardado admite ON_SITE y HPP.

Elige el código fuente para tu aplicación

Un ZIP actual por lenguaje o plataforma móvil, con instrucciones en inglés. Los plugins de tienda siguen separados y las integraciones existentes funcionan.

DEMO DE SERVIDOR · ON_SITE + HPP

PHP

7.0–8.4

Rutas PHP originales: order.php, checkout.php y callback.php

Descargar ZIP
DEMO DE SERVIDOR · ON_SITE + HPP

Node.js

22+

Rutas comunes de servidor y móvil

Descargar ZIP
DEMO DE SERVIDOR · ON_SITE + HPP

Python

3.10+

Rutas comunes de servidor y móvil

Descargar ZIP
DEMO DE SERVIDOR · ON_SITE + HPP

C# / .NET Framework

4.6.1 / VS2019

Rutas comunes de servidor y móvil

Descargar ZIP
DEMO DE SERVIDOR · ON_SITE + HPP

Java

JDK17+

Rutas comunes de servidor y móvil

Descargar ZIP
CÓDIGO MÓVIL · ON_SITE + HPP

iOS Swift

iOS15+ / Xcode14+

Usa un servidor común; proyecto de código fuente

Descargar ZIP
CÓDIGO MÓVIL · ON_SITE + HPP

Android Kotlin

API26+ / SDK35 / JDK17

Usa un servidor común; proyecto de código fuente

Descargar ZIP

Ejecuta el flujo completo del servidor

  1. Configura en privado las credenciales MochiPay, carteras activas, origen HTTPS público del callback y un token de pruebas independiente. El servidor fija el precio; el navegador no puede cambiarlo.
  2. Crea o recupera con el mismo request_id guardado y el contenido original. Firma con HMAC-SHA256 los bytes UTF-8 exactos y las consultas codificadas.
  3. Abre el popup ON_SITE guardado o el redirect HPP: ambos usan el mismo pedido. ON_SITE incluye QR, botones de copia y selector de diez idiomas.
  4. Procesa notify_url en el servidor y consulta el ID guardado. Retorno síncrono y sondeo reutilizan la misma verificación de identidad e importe exacto.
  5. Registra el pago verificado una sola vez. Antes de producción, sustituye archivos y marcas de pruebas por autorización de usuario y actualización atómica en tu base de datos.

PHP conserva order.php / checkout.php / callback.php. Los otros cuatro servidores exponen las siguientes rutas comunes para navegador y móvil.

RutaResponsabilidad
POST /paymentsCrea o recupera un artículo con precio del servidor; request_id, payment_method y token bearer de pruebas.
GET /checkout?r=…&t=…&mode=ON_SITEPopup local del comercio para el pedido guardado.
GET /checkout?…&mode=HPPRedirect 303 tras validar la identidad del pedido y el destino.
GET /status?r=…&t=…Consulta firmada a MochiPay; DTO mínimo con importes como cadenas decimales.
POST /callback?r=…&t=…Verificación asíncrona y marca de pago única.
GET /complete?r=…&t=…Página de retorno síncrono con resultado verificado.

Pago móvil sin secretos API en el móvil

Swift y Kotlin usan cualquiera de los cuatro servidores comunes. Configura solo el origen HTTPS del comercio en la app. ON_SITE muestra el pago local en WKWebView o Android WebView; HPP abre el redirect del comercio en un navegador externo. La app consulta de nuevo al activarse; cerrarla no detiene las notificaciones del servidor.

El ID guardado sobrevive a reintentos y reinicios. Cambiar interfaz o idioma reutiliza el pedido. El token de pruebas es independiente de las credenciales MochiPay: reemplázalo por la sesión autenticada de tu aplicación.

Son ejemplos de integración, no SDK nativos ni aprobaciones de tiendas de apps. Consulta las actualesreglas de facturación de Appleypolíticas de pagos de Google Playpara tu producto y región.

Verifica antes de publicar

Sigue README y TESTING.md de cada paquete. Las pruebas locales firmadas cubren reintentos, identidades incorrectas, estados no pagados y avisos duplicados. Valida en staging con Xcode/Android Studio, dispositivos y un pago real pequeño. No requiere nuevas tablas MochiPay ni reinstalar plugins.

Implementa retornos síncronos y notificaciones asíncronas →

Retornos y notificaciones

Un mismo verificador de servidor procesa retornos síncronos HPP, notificaciones asíncronas HPP y actualizaciones ON_SITE.

Entradas distintas. Una actualización de pedido verificada.

FlujoCampo API / entradaPropósito
Retorno síncrono HPPredirect_url · GET del navegadorMuestra el resultado tras consultar con firma desde el servidor. El cliente puede no volver.
Notificación asíncrona HPPnotify_url · POST del servidorVerifica y actualiza el pedido local sin depender del navegador.
Notificación asíncrona ON_SITEEl mismo notify_url · POST del servidorActualiza el pedido aunque el popup o la app estén cerrados.
Estado ON_SITENavegador/app consulta /status del comercioMuestra solo el resultado mínimo de la misma verificación del servidor.

HPP: retorno síncrono del navegador

Al crear el pago, guarda redirect_url con el token del pedido local. El ejemplo usa HTTPS /complete?r=…&t=…. Después del pago alojado, carga el pedido guardado, valida propietario/token y firma Query Order con el order_id MochiPay guardado.

Muestra PAID solo si pasan la identidad y el importe recibido exacto; si no, espera o revisión. Una URL, mensaje del navegador o captura no acredita el pago. El callback puede llegar antes o después del retorno.

HPP y ON_SITE: notificación asíncrona al servidor

Guarda notify_url al crear; los ejemplos usan /callback?r=…&t=…. MochiPay envía POST independientemente del navegador. Usa los datos recibidos solo como pistas de búsqueda. Consulta la API autenticada y compara ID, referencia, importe/divisa original, activo/red, dirección e importe exacto guardados.

Exige PAID y received_amount exactamente igual a pay_amount. Registra el pago atómicamente una vez; avisos válidos repetidos devuelven OK sin doble actualización ni entrega. Estados sin confirmar, identidades incorrectas y fallos de consulta/almacenamiento no se reconocen como pago exitoso.

Los ejemplos guardan una marca única paid_verified. Sustitúyela por una transacción en tu base de pedidos; no entrega productos. El cuerpo del callback por sí solo nunca actualiza un pedido.

ON_SITE: actualizaciones asíncronas y sondeo del popup

ON_SITE usa el mismo notify_url y sigue verificando con popup cerrado o app offline. Visible, el popup consulta solo tu servidor autorizado cada 15 segundos. El servidor consulta MochiPay y devuelve campos mínimos con importes decimales en texto. PAID usa el mismo verificador del callback; secretos API y datos completos del cliente no llegan al navegador.

Cerrar, reabrir o cambiar ON_SITE/HPP reutiliza el pago guardado. Conserva request_id y contenido exacto tras un timeout; cambiar la referencia puede crear otro pedido.

Código ejecutable en cada paquete de servidor

Cada ejemplo incluye ambos modos, handler de notificación, página de retorno, estado seguro e intento persistido. notify_url y redirect_url son campos API; el modo se elige localmente, no en Create Order.

Node.js · verificación, retorno y notificación

Fragmentos del paquete ejecutable. Variables de rutas y auxiliares de almacenamiento están en el código completo; utiliza la integración completa.

async function verify(r,t){const a=load(r);if(!equal(a.token,t)||!a.snapshot)throw Error('Invalid payment capability');const d=await api('/api/v1/orders/query','order_id='+encodeURIComponent(a.snapshot.order_id));bind(a,d);if(d.status==='PAID'&&!a.paid_verified){a.paid_verified=true;save(r,a)}return d}

// HPP redirect_url -> GET /complete: verify before displaying result.
await verify(r,t);
// notify_url -> POST /callback: same verification and atomic once-only marker.
const d=await verify(r,t);
output(res,d.status==='PAID'?200:409,'text/plain',d.status==='PAID'?'OK':'Payment not confirmed');
// ON_SITE polling -> GET /status: only the safe DTO reaches the browser.
json(res,200,{success:true,data:safe(await verify(r,t))});
Python · verificación, retorno y notificación

Fragmentos del paquete ejecutable. Variables de rutas y auxiliares de almacenamiento están en el código completo; utiliza la integración completa.

def verify(r, t):
    a = load(r)
    if not isinstance(t,str) or not hmac.compare_digest(a['token'],t) or not a.get('snapshot'): raise ValueError('Invalid capability')
    d = api('/api/v1/orders/query',urlencode({'order_id':a['snapshot']['order_id']})); bind(a,d)
    if d.get('status') == 'PAID' and not a['paid_verified']: a['paid_verified'] = True; save(r,a)
    return d

# HPP browser return
verify(r,t)
# HPP and ON_SITE server notification (inside the handler lock)
d = verify(r,t)
self.out(200 if d['status']=='PAID' else 409,'text/plain','OK' if d['status']=='PAID' else 'Payment not confirmed')
# ON_SITE display only
self.jout(200,dict(success=True,data=safe(verify(r,t))))
C# / .NET Framework · verificación, retorno y notificación

Fragmentos del paquete ejecutable. Variables de rutas y auxiliares de almacenamiento están en el código completo; utiliza la integración completa.

        static JObject Verify(string r,string t)
        {
            var a=Load(r);if(!Equal(S(a,"token"),t)||a["snapshot"]==null)throw new Exception("Invalid capability");var d=Api("/api/v1/orders/query",null,"order_id="+Uri.EscapeDataString(S(a["snapshot"],"order_id")));Bind(a,d);
            if(S(d,"status")=="PAID"&&!(bool)a["paid_verified"]){a["paid_verified"]=true;Save(r,a);}return d;
        }

// GET /complete: verified HPP return.
Verify(r,t);
// POST /callback: asynchronous notification for both modes.
var d=Verify(r,t);
Out(res,S(d,"status")=="PAID"?200:409,"text/plain",S(d,"status")=="PAID"?"OK":"Payment not confirmed");
// GET /status: display only the minimal DTO.
JOut(res,200,new JObject {{"success",true},{"data",Safe(Verify(r,t))}});
Java · verificación, retorno y notificación

Fragmentos del paquete ejecutable. Variables de rutas y auxiliares de almacenamiento están en el código completo; utiliza la integración completa.

    static JsonObject verify(String r,String t)throws Exception{JsonObject a=load(r);if(!equal(s(a,"token"),t)||!a.has("snapshot"))throw new IllegalArgumentException("Invalid capability");JsonObject d=api("/api/v1/orders/query",null,"order_id="+enc(s(a.getAsJsonObject("snapshot"),"order_id")));bind(a,d);if(s(d,"status").equals("PAID")&&!a.get("paid_verified").getAsBoolean()){a.addProperty("paid_verified",true);save(r,a);}return d;}

// GET /complete: verified HPP return.
verify(r,t);
// POST /callback: both presentation modes use this route.
boolean paid=s(verify(r,t),"status").equals("PAID");
out(x,paid?200:409,"text/plain",paid?"OK":"Payment not confirmed");
// GET /status: minimal safe display DTO.
jout(x,200,object("success",true,"data",safe(verify(r,t))));
PHP · verificación, retorno y notificación

Fragmentos del paquete ejecutable. Variables de rutas y auxiliares de almacenamiento están en el código completo; utiliza la integración completa.

    // Authenticate the result by querying MochiPay server-to-server.
    $verified = mochipay_query_order('order_id', $orderId);
    if (!$verified['ok'] || !is_array($verified['data'])) {
        callback_text(503, 'VERIFICATION_FAILED');
    }

    $order = $verified['data'];
    if (!isset($order['order_id']) || !hash_equals((string) $order['order_id'], $orderId)) {
        callback_text(409, 'ORDER_MISMATCH');
    }

    $verifiedMerchantId = isset($order['merchant_order_id']) ? (string)$order['merchant_order_id'] : '';
    try { $record = mochipay_load($verifiedMerchantId); }
    catch (Exception $e) { callback_text(503, 'LOCAL_STORAGE_UNAVAILABLE'); }
    if (!mochipay_bound($record, $order) || (isset($callback['merchant_order_id']) && !hash_equals($verifiedMerchantId, (string)$callback['merchant_order_id']))) callback_text(409, 'LOCAL_ORDER_MISMATCH');
    if (!isset($order['received_amount']) || MochiPayPortable::decimal($order['received_amount']) !== MochiPayPortable::decimal($order['pay_amount'])) callback_text(409, 'PAYMENT_AMOUNT_REQUIRES_REVIEW');

    if (!isset($order['status']) || strtoupper((string) $order['status']) !== 'PAID') {
        callback_text(409, 'ORDER_NOT_PAID');
    }

    /*
     * TODO: In your production database, atomically fulfill the bound local order.
     * This demo acknowledges verification only; it does not deliver goods.
     * Make the operation idempotent: repeated callbacks must not deliver goods
     * or credit the customer more than once.
     */
    try { mochipay_record_verified($record, $order); }
    catch (Exception $e) { callback_text(503, 'LOCAL_UPDATE_FAILED'); }
    callback_text(200, 'OK');
}

// GET browser return verifies the saved capability, then queries the saved ID.
$authorized = $record && $returnToken !== '' && hash_equals($record['token'], $returnToken);
if ($authorized) {
    $verified = mochipay_query_order('order_id', $record['snapshot']['order_id']);
    $paid = $verified['ok'] && mochipay_record_verified($record, $verified['data']);
}
Descargar ejemplos completos

Respuestas de error

Errors return an HTTP status code and a stable machine-readable message.

JSON
{ "success": false, "message": "INVALID_SIGNATURE" }
HTTPMensajeDescripción
400INVALID_JSON / INVALID_AMOUNTRequest data is invalid.
400INVALID_CURRENCY / INVALID_PAYMENT_METHODCurrency or payment method is unsupported.
400INVALID_UNIQUE_AMOUNT_DIRECTION / INVALID_PRODUCT_TYPEThe direction or product-type value is unsupported.
400FIELD_TOO_LONG / INVALID_REDIRECT_URL / INVALID_NOTIFY_URLAn optional field exceeds its limit or a supplied URL is invalid.
400ORDER_ID_REQUIRED / ORDER_IDENTIFIER_CONFLICTQuery identifier is missing or conflicting.
401INVALID_API_KEY / INVALID_SIGNATUREError de autenticación.
403SUBSCRIPTION_REQUIRED / SUBSCRIPTION_EXPIREDMerchant subscription is unavailable.
403MERCHANT_DISABLEDMerchant account is disabled.
404ORDER_NOT_FOUNDNo matching merchant-owned order was found.
500SYSTEM_ERRORThe request could not be completed.

Integración de tiendas SaaS clásicas

HPP-only compatibility for Shopyy / Shopoem, Shoplus, Wooshoppaas and Fecify. No plugin download or SaaS source-code change is required.

POST https://mochi.bz/api/v/orders/legacy_create/{MerchantApiKey}/{PaymentMethod}
Use the API key, never the API secret, in this URL. The URL identifies the merchant and payment method. The SaaS platform continues to send its existing application/x-www-form-urlencoded order fields.

Plataformas admitidas

Shopyy / ShopoemSame company and compatible gateway format
ShoplusConfigure the payment interface URL
WooshoppaasConfigure the payment interface URL
FecifyConfigure the payment interface URL

Configuración

  1. Copy the merchant API key from the MochiPay merchant dashboard.
  2. Choose one supported payment method for this SaaS payment option.
  3. Reemplazar {MerchantApiKey}y{PaymentMethod} in the endpoint URL.
  4. Paste the completed URL into the SaaS payment gateway's interface or submit URL setting.
  5. Keep the SaaS platform's existing POST parameters, return URL and notify URL unchanged.

Ejemplos de URL

LEGACY PAYMENT INTERFACE URL
https://mochi.bz/api/v/orders/legacy_create/YOUR_MERCHANT_API_KEY/USDT_TRC20

https://mochi.bz/api/v/orders/legacy_create/YOUR_MERCHANT_API_KEY/USDC_ERC20

https://mochi.bz/api/v/orders/legacy_create/YOUR_MERCHANT_API_KEY/SOL_SOLANA

MÉTODOS DE PAGO

USDT_TRC20USDT on TRON
USDC_ERC20USDC on Ethereum
BTC_BITCOINNative BTC on Bitcoin
ETH_ERC20Native ETH on Ethereum
SOL_SOLANANative SOL on Solana

Campos obligatorios del formato heredado

ParámetroPropósito
merchant_urlOriginal SaaS store value, retained in the complete request record for diagnostics.
system_nameExisting SaaS platform identifier, retained in the complete request record.
account_type / payment_modeKeep the platform's existing values, normally liveysale.
orders_idOriginal SaaS order identifier.
amount / currencyOriginal order amount and currency.
return_urlCustomer return URL after confirmed payment.
notify_urlServer notification URL for the completed payment.
securityTokenOptional passthrough token returned unchanged.
productsOptional product or cart data.
customer_*Existing customer, address, IP and user-agent fields.

Respuesta de creación de pedido

The existing SaaS integration extracts the hosted checkout URL from the three-part plain-text response.

TEXT
_____https://mochi.bz/pay/ORDER_ID_____

Successful return and notification fields

CampoValor
securityTokenThe original passthrough value.
paymentMethodonlinepay
paymentStatusCompleted
paymentTransactionThe confirmed blockchain transaction hash.
paymentCommentsMochiPay payment confirmed
orderIDThe original SaaS orders_id.

Descargas de plugins de comercio

Elige uno de los 19 ZIP independientes según tienda, versión y PHP. Cada ZIP incluye instrucciones en inglés y requisitos PHP. Usa el entorno permitido por tu tienda.

ON-SITE + HPP

WooCommerce

Classic Checkout, Checkout Blocks y HPOS.

PlataformaWooCommerce 5.8 o posterior con API nativa de pasarela
PHPPHP 7.4–8.4

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

OpenCart 2.0–2.2

Rutas de pago antiguas y plantillas específicas por versión.

PlataformaOpenCart 2.0.x-2.2.x
PHPPHP 5.6–7.4; versiones posteriores requieren parches del núcleo

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

OpenCart 2.3

Estructura extension/payment independiente de 2.3.

PlataformaOpenCart 2.3.x
PHPPHP 5.6–7.4; versiones posteriores requieren parches del núcleo

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

OpenCart 3

Vistas Twig y pasarela nativa OpenCart 3.

PlataformaOpenCart 3.0.x
PHPPHP 5.6–8.4; cumple los requisitos exactos del núcleo y dependencias

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

OpenCart 4

Namespaces, rutas y paquetes nativos de 4.x.

PlataformaOpenCart 4.0.2.x-4.1.x
PHPPHP 8.0.2–8.4; 4.1.0.4 requiere 8.1+

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Zen Cart 1.5.3–1.5.7

Archivos de idioma legacy basados en define y estados nativos.

PlataformaZen Cart 1.5.3-1.5.7
PHPPHP 5.6–8.0, según la versión del núcleo

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Zen Cart 1.5.8–2.2

Archivos de idioma modernos basados en arrays y estados nativos.

PlataformaZen Cart 1.5.8 / 2.0.x / 2.1.x / 2.2.x
PHPPHP 7.3–8.4, según la versión del núcleo

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Magento 1 / OpenMage

Magento CE 1.9.3.0–1.9.4.5 y OpenMage 19/20 compatible.

PlataformaMagento CE 1.9.3.0-1.9.4.5; API M1 nativa de OpenMage 19/20
PHPPHP 5.6–8.4; PHP 8 requiere OpenMage compatible

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Magento 2

Magento Open Source 2.3.7–2.4.8 con checkout nativo.

PlataformaMagento Open Source 2.3.7-2.4.8 con checkout nativo
PHPPHP 7.3–8.4, según la versión del núcleo

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

PrestaShop 1.6

Hook de pago y formulario de PrestaShop 1.6.1.

PlataformaPrestaShop 1.6.1.x
PHPPHP 5.6–7.1

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

PrestaShop 1.7 / 8 / 9

PrestaShop 1.7.6–1.7.8, 8.x y 9.0.x con paymentOptions.

PlataformaPrestaShop 1.7.6-1.7.8 / 8.x / 9.0.x
PHPPHP 5.6–8.4, según la versión del núcleo

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Shopware 6.6

Controladores nativos separados para Shopware 6.6 y 6.7.

PlataformaShopware >=6.6.10.0 <6.7.0.0
PHPPHP 8.2.x / 8.3.x / 8.4.x

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Shopware 6.7

Controladores nativos separados para Shopware 6.6 y 6.7.

PlataformaShopware >=6.7.0.0 <6.8.0.0
PHPPHP 8.2.x / 8.3.x / 8.4.x

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Drupal Commerce

Pasarela nativa Commerce para las ramas compatibles de Drupal y Commerce.

PlataformaCommerce 2.40.x with Drupal 9.3–10.x; or Commerce 3.3.10+ <3.4 with Drupal 10.3–11.x
PHPDrupal 9.3–9.5: PHP 7.4–8.1; Drupal 10: PHP 8.1–8.3; Drupal 11: PHP 8.3–8.4, solo si lo permite tu versión exacta de Drupal

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

EC-CUBE 4.3

Checkout JPY nativo con el flujo de compra EC-CUBE.

PlataformaEC-CUBE >=4.3.0 <4.4.0
PHPPHP 8.1.x / 8.2.x / 8.3.x

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Bagisto 2.3

Paquete Laravel con pedidos y facturas nativos.

PlataformaBagisto >=2.3.0 <2.4.0
PHPPHP 8.2.x / 8.3.x / 8.4.x (cumple también las dependencias bloqueadas de la tienda)

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

Sylius 2.0

Checkout Payum nativo y estados de pago Sylius.

PlataformaSylius >=2.0.0 <2.1.0 with PayumBundle 2.6+ / Payum 1.7-compatible core
PHPPHP 8.2.x / 8.3.x / 8.4.x (cumple también las dependencias bloqueadas de la tienda)

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

osCommerce 4.14

Módulo nativo V4; distinto de osCommerce 2.x y 3.x legacy.

PlataformaosCommerce 4.14.x; API nativa del módulo orderPayment V4
PHPPHP 7.4.x–8.3.x, según osCommerce y sus dependencias bloqueadas

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →
ON-SITE + HPP

thirty bees 1.6

Módulo de pago e historial nativos de thirty bees 1.6.

Plataformathirty bees >=1.6.0 <1.7.0
PHPPHP 7.4.x / 8.0.x / 8.1.x / 8.2.x / 8.3.x; usa la distribución correspondiente de thirty bees

Instrucciones en inglés y tabla PHP detallada dentro del ZIP.

Descargar ZIPGuía de configuración →

Los nuevos adaptadores son versiones iniciales. Prueba instalación y pagos reales en staging antes de usarlos en producción.

Empieza a desarrollar con MochiPay

Crea una cuenta y elige la integración adecuada.

Comenzar