RESSOURCES DÉVELOPPEUR

Développement API

Référence API, exemples serveur et mobile, retours et notifications dans un seul guide. PHP, Node.js, Python, C#, Java, iOS Swift et Android Kotlin prennent en charge ON_SITE et HPP.

REST API · INTERFACE DE PAIEMENT

Une commande. ON_SITE ou HPP.

Créez et liez la commande sur votre serveur puis choisissez la présentation. Les deux modes conservent order_id.

ConsultezRetours synchrones HPP et notifications asynchrones ON_SITE/HPP, avec du code PHP, Node.js, Python, C# et Java.

ON_SITE

Fenêtre de paiement dans votre boutique

Affichez montant, adresse, réseau et QR dans votre fenêtre. Votre serveur consulte et renvoie une vue sûre.

Voir HTML et PHP →
HPP

Rediriger vers le paiement MochiPay

Redirigez vers payment_url et vérifiez retour ou notification par Query Order authentifié.

Voir la redirection PHP →

Extraits de checkout.php et des utilitaires PHP Demo 1.1.4 (PHP 7.0–8.4). Créez d’abord avec order.php pour obtenir les deux liens. En production, chargez la commande autorisée depuis la session/base de données et finalisez-la par une transaction idempotente.

Rediriger après vérification serveur

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.

Afficher la fenêtre dans votre page

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.

Votre serveur vérifie la commande

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.

Authentification

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

En-têteobligatoireDescription
X-Mochi-KeyOuiYour merchant API key.
X-Mochi-SignatureOuiBase64-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.

Signature

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)))

Devises prises en charge

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

DEVISES DE COMMANDE

28 supported fiat currencies

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

USDEURGBPCAD AUDNZDJPYCNY HKDSGDCHFSEK NOKDKKPLNCZK HUFAEDSARINR IDRTHBMYRPHP KRWBRLMXNZAR
CRYPTO ORDER CURRENCIES

Prix en cryptomonnaie

Orders may also be priced directly in these cryptocurrencies.

USDTUSDCBTCETHSOL
MOYENS DE PAIEMENT

Supported cryptocurrency and network combinations

Send one of these exact values in the payment_method Champ.

USDT_TRC20USDT on TRON
USDC_ERC20USDC on Ethereum
BTC_BITCOINNative BTC on Bitcoin
ETH_ERC20Native ETH on Ethereum
SOL_SOLANANative SOL on Solana
Règle de conversion : 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 →
Valeur de commandeMoyen de paiementRésultat
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.

Créer une commande

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

Paramètres de requête

Order currency and payment method are different concepts. amountetcurrency 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 avec USDT_TRC20 means that a USD-denominated order is paid with the calculated amount of USDT on the TRON network.
ParamètreobligatoireType / longueurDescription
merchant_order_idOuistring · 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.
amountOuidecimal(28,8)Positive original order amount. Fiat normally uses 2 decimal places; supported cryptocurrencies may use up to 8.
currencyOuistring · 1–20Original order currency code. It may be fiat, such as USD ou EUR, or cryptocurrency, such as USDT ou USDC.
payment_methodOuiasset ≤20 + network ≤30Payment cryptocurrency and blockchain network in ASSET_NETWORK format, such as USDT_TRC20 ou USDC_ERC20.
unique_amount_directionNonUP ou DOWNDirection used for the small unique amount adjustment. Defaults to UP.
product_typeNonPHYSICAL ou DIGITAL_SERVICEOrder type displayed at checkout. Defaults to DIGITAL_SERVICE. Shipping fields remain optional for both types.
descriptionNonstring · 0–500Human-readable order description.
product_infoNonJSON/string · nvarchar(max)Product, cart or custom metadata. The complete HTTP request body must not exceed 65,536 bytes.
customer_emailNonstring · 0–255Customer email address. When supplied, it must be a valid email address.
customer_phoneNonstring · 0–50Customer telephone number.
first_nameNonstring · 0–100Customer first name.
last_nameNonstring · 0–100Customer last name.
companyNonstring · 0–200Customer company or organization name.
countryNonstring · 0–100Customer country or region.
stateNonstring · 0–100Customer state, province or region.
cityNonstring · 0–100Customer city.
address1Nonstring · 0–500Primary customer address line.
address2Nonstring · 0–500Additional customer address line.
postal_codeNonstring · 0–30Customer postal or ZIP code.
request_idNonstring · 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_urlNonstring · 0–1000Absolu http:// ou https:// asynchronous server notification URL. Only public destinations are allowed; localhost, private/reserved IPs and redirects are blocked.
redirect_urlNonstring · 0–1000Absolute customer return URL used after a successful payment.
customer_ipNonIPv4/IPv6 · 0–45Customer IP supplied by the merchant. MochiPay also records the API request IP separately.

Exemple de requête

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.');
}
?>

Réponse de réussite

ChampType / longueurDescription
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"
}

Consulter une commande

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

GET https://mochi.bz/api/v1/orders/query
Paramètre de requêteobligatoireType / longueurDescription
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.
Utiliser 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.

Exemples de requête

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.');
}
?>

Champs de la réponse de réussite

The query returns wallet_typeetnetwork 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.

ChampType / longueurDescription
order_idstring · 32MochiPay order identifier.
merchant_order_idstring · ≤100Your merchant order identifier.
sourcestring · ≤20Order source, such as API.
descriptionstring · ≤500Order description.
product_typestring · ≤20PHYSICAL ou 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 ou 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 ou 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 · ≤20Actif de paiement: USDT, USDC, BTC, ETH ou SOL.
networkstring · ≤30Blockchain network, such as TRC20 ou 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.

Exemples de code

PHP, Node.js, Python, C# / .NET Framework, Java, iOS Swift et Android Kotlin. Un paiement enregistré prend en charge ON_SITE et HPP.

Choisissez les sources pour votre application

Un ZIP actuel par langage ou plateforme mobile, avec instructions en anglais. Les plugins restent séparés et les intégrations existantes fonctionnent.

DÉMO SERVEUR · ON_SITE + HPP

PHP

7.0–8.4

Routes PHP d’origine : order.php, checkout.php et callback.php

Télécharger ZIP
DÉMO SERVEUR · ON_SITE + HPP

Node.js

22+

Routes communes serveur et mobile

Télécharger ZIP
DÉMO SERVEUR · ON_SITE + HPP

Python

3.10+

Routes communes serveur et mobile

Télécharger ZIP
DÉMO SERVEUR · ON_SITE + HPP

C# / .NET Framework

4.6.1 / VS2019

Routes communes serveur et mobile

Télécharger ZIP
DÉMO SERVEUR · ON_SITE + HPP

Java

JDK17+

Routes communes serveur et mobile

Télécharger ZIP
SOURCES MOBILES · ON_SITE + HPP

iOS Swift

iOS15+ / Xcode14+

Utilise un serveur commun ; projet source uniquement

Télécharger ZIP
SOURCES MOBILES · ON_SITE + HPP

Android Kotlin

API26+ / SDK35 / JDK17

Utilise un serveur commun ; projet source uniquement

Télécharger ZIP

Exécuter le parcours serveur complet

  1. Configurez en privé les identifiants MochiPay, portefeuilles actifs, origine HTTPS publique du callback et jeton de test indépendant. Le serveur fixe le prix ; le navigateur ne peut pas le modifier.
  2. Créez ou récupérez avec le même request_id enregistré et le contenu d’origine. Signez par HMAC-SHA256 les octets UTF-8 exacts et les requêtes encodées.
  3. Ouvrez le popup ON_SITE enregistré ou la redirection HPP ; les deux utilisent la même commande. ON_SITE inclut QR, boutons de copie et choix de dix langues.
  4. Traitez notify_url côté serveur et interrogez l’ID enregistré. Retour synchrone et interrogation périodique utilisent la même vérification d’identité et de montant exact.
  5. Enregistrez le paiement vérifié une seule fois. Avant production, remplacez les fichiers et marqueurs de test par l’autorisation utilisateur et une mise à jour atomique de votre base.

PHP conserve order.php / checkout.php / callback.php. Les quatre autres serveurs exposent les routes communes suivantes pour navigateur et mobile.

RouteResponsabilité
POST /paymentsCréer ou récupérer un article au prix fixé par le serveur ; request_id, payment_method et jeton bearer de test.
GET /checkout?r=…&t=…&mode=ON_SITEPopup de paiement local du marchand pour la commande enregistrée.
GET /checkout?…&mode=HPPRedirection 303 après validation de l’identité et de la destination.
GET /status?r=…&t=…Requête signée à MochiPay ; DTO minimal avec montants en chaînes décimales.
POST /callback?r=…&t=…Vérification asynchrone et marqueur de paiement unique.
GET /complete?r=…&t=…Page de retour synchrone avec résultat vérifié.

Paiement mobile sans secrets API dans l’application

Swift et Kotlin utilisent l’un des quatre serveurs communs. Configurez uniquement l’origine HTTPS du marchand dans l’app. ON_SITE affiche le checkout local dans WKWebView ou Android WebView ; HPP ouvre la redirection marchand dans un navigateur externe. L’app vérifie à nouveau à son activation ; la fermer n’arrête pas les notifications serveur.

L’ID enregistré persiste après réessais et redémarrages. Changer l’interface ou la langue réutilise la commande. Le jeton de test est distinct des identifiants MochiPay ; remplacez-le par la session utilisateur authentifiée de votre application.

Ce sont des exemples d’intégration, pas des SDK natifs ni des autorisations de publication. Consultez les dernièresrègles de facturation Appleetrègles de paiement Google Playpour votre produit et région.

Vérifier avant la mise en ligne

Suivez README et TESTING.md de chaque paquet. Les tests locaux signés couvrent réessais, identités incorrectes, états impayés et notifications dupliquées. Validez en staging avec Xcode/Android Studio, appareils réels et un petit paiement réel. Aucune nouvelle table MochiPay ni réinstallation de plugin nécessaire.

Implémenter retours synchrones et notifications asynchrones →

Retours et notifications

Un même vérificateur serveur traite les retours synchrones HPP, notifications asynchrones HPP et mises à jour ON_SITE.

Plusieurs entrées. Une mise à jour de commande vérifiée.

ParcoursChamp API / entréeObjectif
Retour synchrone HPPredirect_url · GET du navigateurAfficher le résultat après une requête signée du serveur. Le client peut ne jamais revenir.
Notification asynchrone HPPnotify_url · POST serveurVérifier et mettre à jour la commande locale sans dépendre du navigateur.
Notification asynchrone ON_SITELe même notify_url · POST serveurMettre à jour même si le popup ou l’app est fermé.
Affichage du statut ON_SITELe navigateur/app interroge /status du marchandAfficher le résultat minimal de la même vérification serveur.

HPP : retour synchrone du navigateur

À la création, enregistrez redirect_url avec le jeton de la commande locale. L’exemple utilise HTTPS /complete?r=…&t=…. Après checkout hébergé, chargez la commande, validez propriétaire/jeton puis signez Query Order avec l’order_id MochiPay enregistré.

Affichez PAID uniquement après validation de l’identité et du montant exact reçu ; sinon attente ou examen. URL, message navigateur ou capture ne prouvent pas le paiement. Le callback peut précéder ou suivre le retour.

HPP et ON_SITE : notification asynchrone serveur

Enregistrez notify_url à la création ; exemples : /callback?r=…&t=…. MochiPay envoie POST indépendamment du navigateur. Les données entrantes servent seulement à retrouver la commande. Interrogez l’API authentifiée et comparez ID, référence, montant/devise d’origine, actif/réseau, adresse et montant exact enregistrés.

Exigez PAID et received_amount exactement égal à pay_amount. Enregistrez atomiquement une seule fois ; les notifications valides répétées retournent OK sans double mise à jour ni livraison. États non confirmés, identités invalides et erreurs de requête/stockage ne doivent pas être reconnus comme paiement réussi.

Les démos enregistrent un marqueur unique paid_verified. Remplacez-le par une transaction dans votre base de commandes ; il ne livre pas de produits. Le corps du callback seul ne déclenche jamais de mise à jour.

ON_SITE : mises à jour asynchrones et interrogation du popup

ON_SITE utilise le même notify_url et continue la vérification même popup fermé ou app hors ligne. Visible, le popup interroge uniquement votre serveur autorisé toutes les 15 secondes. Le serveur interroge MochiPay et retourne les champs minimaux, montants en chaînes décimales. PAID utilise le même vérificateur que le callback ; secrets API et réponse client complète ne vont pas au navigateur.

Fermer, rouvrir ou changer ON_SITE/HPP réutilise le paiement enregistré. Conservez request_id et contenu exact après un délai dépassé ; changer la référence peut créer une commande supplémentaire.

Code exécutable dans chaque paquet serveur

Chaque exemple inclut les deux modes, notifications, retour, statut sécurisé et tentative persistée. notify_url et redirect_url sont des champs API ; le mode est un choix local, pas un champ Create Order.

Node.js · vérification, retour et notification

Extraits du paquet exécutable. Variables de routes et utilitaires de stockage sont définis dans les sources complètes ; utilisez l’intégration complète.

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 · vérification, retour et notification

Extraits du paquet exécutable. Variables de routes et utilitaires de stockage sont définis dans les sources complètes ; utilisez l’intégration complète.

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 · vérification, retour et notification

Extraits du paquet exécutable. Variables de routes et utilitaires de stockage sont définis dans les sources complètes ; utilisez l’intégration complète.

        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 · vérification, retour et notification

Extraits du paquet exécutable. Variables de routes et utilitaires de stockage sont définis dans les sources complètes ; utilisez l’intégration complète.

    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 · vérification, retour et notification

Extraits du paquet exécutable. Variables de routes et utilitaires de stockage sont définis dans les sources complètes ; utilisez l’intégration complète.

    // 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']);
}
Télécharger les exemples complets

Réponses d’erreur

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

JSON
{ "success": false, "message": "INVALID_SIGNATURE" }
HTTPMessageDescription
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_SIGNATUREÉchec de l’authentification.
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.

Intégration de boutiques SaaS classiques

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.

Plateformes prises en charge

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

Configuration

  1. Copy the merchant API key from the MochiPay merchant dashboard.
  2. Choose one supported payment method for this SaaS payment option.
  3. Remplacer {MerchantApiKey}et{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.

Exemples d’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

MOYENS DE PAIEMENT

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

Champs obligatoires du format historique

ParamètreObjectif
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 liveetsale.
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.

Réponse de création de commande

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

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

Téléchargements de plugins e-commerce

Choisissez l’un des 19 ZIP distincts selon boutique, version et PHP. Chaque ZIP inclut instructions en anglais et exigences PHP. Respectez l’environnement permis par votre boutique.

ON-SITE + HPP

WooCommerce

Classic Checkout, Checkout Blocks et HPOS.

PlateformeWooCommerce 5.8 ou ultérieur avec API native de passerelle
PHPPHP 7.4–8.4

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

OpenCart 2.0–2.2

Anciennes routes de paiement et modèles propres aux versions.

PlateformeOpenCart 2.0.x-2.2.x
PHPPHP 5.6–7.4 ; les versions ultérieures nécessitent des correctifs du cœur

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

OpenCart 2.3

Structure extension/payment distincte de 2.3.

PlateformeOpenCart 2.3.x
PHPPHP 5.6–7.4 ; les versions ultérieures nécessitent des correctifs du cœur

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

OpenCart 3

Vues Twig et passerelle native OpenCart 3.

PlateformeOpenCart 3.0.x
PHPPHP 5.6–8.4 ; respectez les exigences du cœur et des dépendances

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

OpenCart 4

Espaces de noms, routes et packages natifs 4.x.

PlateformeOpenCart 4.0.2.x-4.1.x
PHPPHP 8.0.2–8.4 ; 4.1.0.4 nécessite 8.1+

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Zen Cart 1.5.3–1.5.7

Fichiers de langue historiques basés sur define et états natifs.

PlateformeZen Cart 1.5.3-1.5.7
PHPPHP 5.6–8.0, selon la version du cœur

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Zen Cart 1.5.8–2.2

Fichiers de langue modernes basés sur des tableaux et états natifs.

PlateformeZen Cart 1.5.8 / 2.0.x / 2.1.x / 2.2.x
PHPPHP 7.3–8.4, selon la version du cœur

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Magento 1 / OpenMage

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

PlateformeMagento CE 1.9.3.0-1.9.4.5 ; API M1 native OpenMage 19/20
PHPPHP 5.6–8.4 ; PHP 8 nécessite un cœur OpenMage compatible

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Magento 2

Magento Open Source 2.3.7–2.4.8 avec paiement natif.

PlateformeMagento Open Source 2.3.7-2.4.8 avec paiement natif
PHPPHP 7.3–8.4, selon la version du cœur

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

PrestaShop 1.6

Hook de paiement et formulaire PrestaShop 1.6.1.

PlateformePrestaShop 1.6.1.x
PHPPHP 5.6–7.1

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

PrestaShop 1.7 / 8 / 9

PrestaShop 1.7.6–1.7.8, 8.x et 9.0.x avec paymentOptions.

PlateformePrestaShop 1.7.6-1.7.8 / 8.x / 9.0.x
PHPPHP 5.6–8.4, selon la version du cœur

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Shopware 6.6

Gestionnaires natifs distincts pour Shopware 6.6 et 6.7.

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

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Shopware 6.7

Gestionnaires natifs distincts pour Shopware 6.6 et 6.7.

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

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Drupal Commerce

Passerelle Commerce native pour les branches Drupal et Commerce compatibles.

PlateformeCommerce 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, uniquement si la version exacte de Drupal l’autorise

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

EC-CUBE 4.3

Paiement JPY natif avec le parcours d’achat EC-CUBE.

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

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Bagisto 2.3

Package Laravel avec commandes et factures natives.

PlateformeBagisto >=2.3.0 <2.4.0
PHPPHP 8.2.x / 8.3.x / 8.4.x (respectez aussi les dépendances verrouillées de la boutique)

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

Sylius 2.0

Paiement Payum natif et états de paiement Sylius.

PlateformeSylius >=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 (respectez aussi les dépendances verrouillées de la boutique)

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

osCommerce 4.14

Module natif V4 ; distinct des anciens osCommerce 2.x et 3.x.

PlateformeosCommerce 4.14.x ; API native du module orderPayment V4
PHPPHP 7.4.x–8.3.x, selon osCommerce installé et ses dépendances verrouillées

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →
ON-SITE + HPP

thirty bees 1.6

Module de paiement et historique natifs pour thirty bees 1.6.

Plateformethirty bees >=1.6.0 <1.7.0
PHPPHP 7.4.x / 8.0.x / 8.1.x / 8.2.x / 8.3.x ; utilisez la distribution thirty bees adaptée

Instructions en anglais et tableau PHP détaillé dans le ZIP.

Télécharger ZIPGuide de configuration →

Les nouveaux adaptateurs sont initiaux. Testez installation et paiements réels en préproduction avant utilisation réelle.

Commencez à développer avec MochiPay

Créez un compte et choisissez l’intégration adaptée.

Commencer