開發者資源

API 開發

介面參考、服務端與手機端示例、付款返回及通知統一在此檢視。PHP、Node.js、Python、C#、Java、iOS Swift 和 Android Kotlin 均支援 ON_SITE 與 HPP。

REST API · 結賬介面

同一付款訂單,選擇 ON_SITE 或 HPP。

在伺服器建立訂單並儲存本地繫結,再選擇客戶付款介面,兩種模式使用同一 order_id。

參見 HPP 同步返回與 ON_SITE/HPP 非同步通知處理,附 PHP、Node.js、Python、C# 和 Java 程式碼。

ON_SITE

結賬中的付款對話方塊

在您自己網域的對話方塊中顯示確切的金額、位址、網路和二維碼。您的後端查詢 MochiPay 並傳回安全支付視圖。

檢視內嵌 HTML + PHP →
HPP

跳轉到 MochiPay 結賬

伺服器將客戶跳轉至 payment_url;付款後透過認證的訂單查詢驗證返回或通知。

檢視 PHP 跳轉示例 →

以下程式碼節選自 PHP Demo 1.1.4 的 checkout.php 及配套輔助函式(PHP 7.0–8.4)。先用 order.php 建立訂單,其結果提供兩種模式的入口。正式接入應從會話或資料庫讀取已授權的本地訂單,並透過冪等事務完成訂單更新。

服務端核實後跳轉

HPP · PHP

驗證已儲存的訂單繫結與目標地址,再在任何頁面輸出前傳送 Location 響應頭。

checkout.php · HPP 分支
// 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.

完整檔案在進入此分支前載入已儲存嘗試,驗證令牌、認證查詢及預期 payment_url。

在自己的頁面內顯示付款彈窗

ON_SITE · PHP + HTML

在結賬 HTML 引入本地對話方塊資源,瀏覽器只與本地輪詢介面通訊,不簽名,也不接收 API 憑證。

checkout.php · 本地對話方塊資源
// 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 在現有頁面上開啟對話方塊,關閉後仍保留結賬頁;重新開啟按鈕複用同一付款。

由後端核實訂單

驗證已儲存的編號/令牌許可權,透過儲存的 MochiPay order_id 查詢並核對原始金額/幣種、資產/網路、地址和準確應付金額。僅返回以十進位制字串表示的安全支付資訊。

order.php · 本地輪詢介面
// 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.

完整演示還會核對 PAID 狀態下的實收金額,callback.php 會驗證通知和瀏覽器返回。截圖、跳轉或瀏覽器標記均不能證明付款。

測試您的付款接入

在商戶後台的「付款模式」啟用 Sandbox。API 憑證、請求地址、訂單查詢校驗和通知處理方式均不變。正式收款前切換回 Live。

Sandbox 使用演示二維碼與模擬金額,不代表收款錢包或實際匯率。可在 HPP 或更新後的 ON_SITE 彈窗點擊模擬付款。模擬成功可能觸發商城原有的出貨或開通流程,請使用測試商城。

支付模式 · 外掛下載

身份驗證

每次 API 請求均需商戶 API Key 和 Base64 編碼的 HMAC-SHA256 簽名。

請求頭必填說明
X-Mochi-Key是的你的商戶 API Key。
X-Mochi-Signature是的Base64 編碼的 HMAC-SHA256 簽名。
Content-TypePOST 請求application/json
API Secret 保留在伺服器。 絕不能在瀏覽器 JavaScript、移動應用或公開原始碼中暴露它。

簽名

建立訂單時,對原始 JSON 請求正文簽名;查詢訂單時,對去掉開頭符號的原始查詢字串簽名 ?.

簽名公式
Base64(HMAC-SHA256(UTF8(signing_text), UTF8(api_secret)))

支援的幣種

訂單幣種用於購買定價,支付方式決定付款使用的加密貨幣與區塊鏈網路。

訂單幣種

支援 28 種法幣

在以下引數中使用這些準確的 ISO 程式碼之一: currency 欄位。

USDEURGBPCAD AUDNZDJPYCNY HKDSGDCHFSEK NOKDKKPLNCZK HUFAEDSARINR IDRTHBMYRPHP KRWBRLMXNZAR
加密貨幣訂單幣種

加密貨幣定價

訂單也可以直接使用這些加密貨幣定價。

USDTUSDCBTCETHSOLTRX
支付方式

支援的加密貨幣與網路組合

在以下引數中填寫這些準確值之一: payment_method 欄位。

USDT_TRC20USDT 上 TRON
USDC_ERC20在伊特魯姆的USDC
BTC_BITCOINBitcoin 網路原生 BTC
ETH_ERC20Ethereum 網路原生 ETH
SOL_SOLANASolana 網路原生 SOL
TRX_TRONTRON 網路原生 TRX
換算規則: 訂單幣種與支付資產相同時,MochiPay 使用匯率 1 ,無需換算;其他情況在建立訂單時應用儲存的匯率及商戶加價。 檢視當前參考匯率 →
訂單金額付款方式結果
49.90 USDUSDT_TRC20使用已儲存的 USD → USDT 匯率和商戶加價。
100 EURBTC_BITCOIN使用已儲存的 EUR → BTC 匯率和商戶加價。
25 USDCUSDC_ERC20無需換算,匯率為 1.

建立訂單

建立付款訂單,獲取託管付款 URL 以及站內介面所需的付款說明。

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

請求引數

訂單幣種與支付方式是不同概念。 amount 與 currency 定義商戶的原始訂單金額。 payment_method 定義顧客支付使用的加密貨幣及區塊鏈網路。例如, 49.90 USD 使用 USDT_TRC20 表示以 USD 計價的訂單,使用計算出的 USDT 數量在 TRON 網路付款。

每次新結賬都會建立新訂單,即使 merchant_order_id 重複也不例外。

開單超時不代表開單失敗。先用開單前儲存的 request_id 查詢結果。

結果不確定時,查詢已儲存的 request_id;merchant_order_id 只是商戶訂單參考號。

引數必填型別 / 長度說明
request_id選填,建議提供string · 1–64由你的程式在開單前生成並儲存的請求編號。查詢或重試同一次付款請求時,繼續使用這個編號。
merchant_order_id是的string · 1–100商店自己的訂單號,區分大小寫,可以重複。若對應多筆付款,請改用 request_id 或 order_id 查詢。
amount是的decimal(28,8)原始訂單金額須為正數;法幣通常使用 2 位小數,支援的加密貨幣最多可用 8 位。
currency是的string · 1–20原始訂單幣種程式碼,可以是法幣,例如 USD 或 EUR,也可以是加密貨幣,例如 USDT 或 USDC.
payment_method否資產程式碼 ≤20 + 網路程式碼 ≤30支付使用的加密貨幣及區塊鏈網路,對應 ASSET_NETWORK 格式,例如 USDT_TRC20 或 USDC_ERC20.
unique_amount_direction否UP 或 DOWN唯一金額微調方向,預設為 UP.
product_type否PHYSICAL 或 DIGITAL_SERVICE結賬頁展示的訂單型別,預設為 DIGITAL_SERVICE。兩種型別的配送欄位均為可選。
description否string · 0–500易於閱讀的訂單說明。
product_info否JSON/字串 ^ nvarchar(最大)商品、購物車或自定義後設資料,完整 HTTP 請求體不得超過 65,536 位元組。
customer_email否string · 0–255客戶郵箱;若提供,必須為有效郵箱地址。
customer_phone否string · 0–50客戶電話號碼。
first_name否string · 0–100客戶名字。
last_name否string · 0–100客戶姓氏。
company否string · 0–200客戶公司或組織名稱。
country否string · 0–100客戶所在國家或地區。
state否string · 0–100客戶所在州、省或地區。
city否string · 0–100客戶所在城市。
address1否string · 0–500客戶主要收貨地址。
address2否string · 0–500客戶附加地址資訊。
postal_code否string · 0–30客戶郵政編碼。
notify_url否string · 0–1000絕對值 http:// 或 https:// 非同步通知地址。僅允許公網接收端,攔截 localhost、內網或保留地址及重定向。
redirect_url否string · 0–1000付款成功後使用的完整客戶返回 URL。
customer_ip否IPv4/IPv6 − 0–45 (英語).商戶提供的客戶 IP;MochiPay 另行記錄 API 請求 IP。

payment_method 缺少、為空或不支援時,進入 HPP 選擇。有效值仍直接付款。產生 QR 碼後鎖定所選方式。

請求示例

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# · 建立訂單
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 · 建立訂單
<?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 => true,
    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.');
}
?>

成功響應

領域型別 / 長度說明
successboolean建立成功時為 true。
order_idstring · 32MochiPay 系統標識,請與本地訂單一同儲存。
merchant_order_idstring · ≤100你的原始商戶訂單編號。
product_typestring · ≤20PHYSICAL 或 DIGITAL_SERVICE。
statusstring · ≤20當前付款狀態。
amountdecimal(28,8)原始訂單金額;必須保留小數精度。
currencystring · ≤20原始定價幣種。
base_pay_amountdecimal(28,8)唯一金額調整前的換算數量。
unique_amount_deltadecimal(28,8)帶方向的金額匹配調整。
unique_amount_directionstring · ≤10UP 或 DOWN。
pay_amountdecimal(28,8)用於展示和轉賬的精確鏈上數量,不能取整。
payment_methodstring所選資產 / 網路,例如 USDT_TRC20。
payment_addressstring · ≤255本筆付款及其網路的收款地址。
payment_urlstring · URLHPP URL;站內支付使用相同訂單的付款說明。
expires_atdatetime到期時間,格式 yyyy-MM-dd HH:mm:ss。
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"
}

查詢訂單

使用且僅使用一個訂單標識,查詢屬於已認證商戶的訂單。

GET https://mochi.bz/api/v1/orders/query
查詢引數必填型別 / 長度說明
request_id三選一string · 1–64由你的程式在開單前生成並儲存的請求編號。查詢或重試同一次付款請求時,繼續使用這個編號。
order_id三選一string · 1–32MochiPay 開單成功後返回的訂單編號。
merchant_order_id三選一string · 1–100商店自己的訂單號,區分大小寫,可以重複。若對應多筆付款,請改用 request_id 或 order_id 查詢。

查詢時三選一即可:request_id、order_id 或 merchant_order_id,不要同時傳多個。

  1. 開單超時不代表開單失敗。先用開單前儲存的 request_id 查詢結果。
  2. 如果查到訂單,就繼續使用這筆訂單,不要再建立另一筆付款。
  3. 只有已驗證簽名的查詢結果同時返回 ORDER_NOT_FOUND 和 recovery_contract=request-id-v1(確認原請求可重試),才重新傳送原開單請求;request_id 和請求正文都保持不變。
  4. 如果驗籤失敗或結果仍不明確,保留原請求,稍後再查,不要換一個 request_id 重新開單。

查詢示例

C# · 查詢訂單
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 · 查詢訂單
<?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 => true,
    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.');
}
?>

selection_required=true 時,payment_method 和 payment_address 為空,pay_amount 為 0。請導向 payment_url。確認選擇後 order_id 和原截止時間維持不變。

成功響應欄位

查詢返回 wallet_type 與 network 分別傳入;建立訂單會返回組合後的 payment_method。與本地訂單儲存的支付方式核對,僅向顧客瀏覽器返回必要付款欄位。

領域型別 / 長度說明
order_idstring · 32MochiPay 訂單標識。
merchant_order_idstring · ≤100你的商戶訂單標識。
sourcestring · ≤20訂單來源,例如 API.
descriptionstring · ≤500訂單說明。
product_typestring · ≤20PHYSICAL 或 DIGITAL_SERVICE.
product_infoJSON/弦/無建立訂單時提供的商品或購物車資訊。
statusstring · ≤20訂單整體付款狀態。
merchant_statusstring · ≤50商戶看到的訂單狀態。
amountdecimal(28,8)原始訂單金額。
currencystring · ≤20原始訂單幣種,例如 USD, EUR, USDT 或 USDC.
base_pay_amountdecimal(28,8)用於唯一匹配調整前的換算付款數量。
unique_amount_deltadecimal(28,8)在基礎數量上增加或減少的小額定向調整。
unique_amount_directionstring · ≤10UP 或 DOWN.
pay_amountdecimal(28,8)客戶必須支付的精確加密貨幣數量。
received_amountdecimal(28,8)目前收到的加密貨幣數量。
manual_payment_acceptedBooleanSeparate authenticated proof of an operator acceptance; never infer it from PAID alone.
exchange_ratedecimal(38,18)訂單建立時使用的匯率快照。
rate_markup_percentdecimal(9,4)本訂單使用的商戶匯率加價快照。
wallet_typestring · ≤20支付資產: USDT, USDC, BTC, ETH SOL 或 TRX.
networkstring · ≤30區塊鏈網路,例如 TRC20 或 ERC20.
payment_addressstring · ≤255本訂單選擇的商戶收款地址。
tx_hashstring/null · ≤255檢測到的客戶付款交易雜湊。
confirmationsinteger當前區塊鏈確認數。
customer_email … postal_codestring/null建立訂單時提供的可選客戶與收貨欄位。
payment_urlstring · URLHPP 結賬 URL;站內接入查詢同一訂單獲取狀態和付款說明。
expires_atdatetime訂單到期時間。
paid_atdatetime/null付款完成時間。
created_atdatetime訂單建立時間。
updated_atdatetime訂單最近更新時間。

程式碼示例

提供 PHP、Node.js、Python、C# / .NET Framework、Java、iOS Swift 和 Android Kotlin 示例。已儲存的同一付款訂單可用於 ON_SITE 和 HPP。

Packagist 上的 PHP SDK

透過 Composer 安裝 PHP SDK。

從 PHP 後端建立和查詢付款訂單。API 憑據請儲存在伺服器上。

v1.0.2 · PHP 7.4+ · MIT

composer require mochipay/php-sdk:^1.0

資源免費下載,實際收款按訂閱付費。

檢視訂閱方案

選擇適合應用的原始碼包

每種開發語言或手機平臺提供一個最新版 ZIP,內含英文安裝說明。商城外掛仍單獨提供,現有接入繼續相容。

服務端示例 · ON_SITE + HPP

PHP

7.0–8.4

保留 PHP 入口:order.php、checkout.php 和 callback.php

下載 ZIP
服務端示例 · ON_SITE + HPP

Node.js

22+

通用手機端與服務端介面

下載 ZIP
服務端示例 · ON_SITE + HPP

Python

3.10+

通用手機端與服務端介面

下載 ZIP
服務端示例 · ON_SITE + HPP

C# / .NET Framework

4.6.1 / VS2019

通用手機端與服務端介面

下載 ZIP
服務端示例 · ON_SITE + HPP

Java

JDK17+

通用手機端與服務端介面

下載 ZIP
手機端原始碼 · ON_SITE + HPP

iOS Swift

iOS15+ / Xcode14+

配合通用後端使用;提供原始碼專案

下載 ZIP
手機端原始碼 · ON_SITE + HPP

Android Kotlin

API26+ / SDK35 / JDK17

配合通用後端使用;提供原始碼專案

下載 ZIP

執行完整的服務端付款流程

  1. 在服務端配置 MochiPay 憑據、有效收款錢包、公開 HTTPS 回撥地址和獨立的測試訪問令牌。示例價格由服務端確定,瀏覽器不能修改。
  2. 使用已儲存的同一 request_id 和原始請求內容建立或恢復付款。按實際 UTF-8 請求位元組和編碼後的查詢字串計算 HMAC-SHA256 簽名。
  3. 開啟已儲存訂單的 ON_SITE 彈窗或跳轉到 HPP。兩種模式使用同一付款訂單。ON_SITE 提供二維碼、複製按鈕和十種語言選擇。
  4. 在服務端處理 notify_url,並按已儲存的訂單 ID 重新查詢。同步返回和輪詢入口使用相同的訂單繫結及精確金額校驗。
  5. 核實付款後僅記錄一次已付款狀態。正式上線前,將示例的檔案儲存和標記替換為應用自身的使用者許可權校驗及資料庫原子更新。

PHP 保留 order.php / checkout.php / callback.php 流程。其餘四種服務端示例提供以下通用介面,供瀏覽器和手機應用呼叫。

介面入口職責
POST /payments建立或恢復由服務端定價的付款;使用 request_id、payment_method 及測試訪問令牌。
GET /checkout?r=…&t=…&mode=ON_SITE為已儲存訂單開啟商戶本地付款彈窗。
GET /checkout?…&mode=HPP校驗訂單繫結及目標地址後,以 HTTP 303 跳轉。
GET /status?r=…&t=…簽名查詢 MochiPay;僅返回必要付款欄位,金額保留為十進位制字串。
POST /callback?r=…&t=…非同步核實付款,並僅記錄一次已付款標記。
GET /complete?r=…&t=…核實訂單後的同步返回與結果頁。

手機端結賬,API 金鑰留在服務端

Swift 和 Kotlin 原始碼專案可配合四種通用後端中的任意一種。應用內只配置商戶 HTTPS 地址。ON_SITE 在 WKWebView 或 Android WebView 顯示商戶結賬頁;HPP 透過外部瀏覽器開啟商戶跳轉入口。應用恢復前臺時會重新查詢後端,關閉應用不會中斷服務端通知。

重試或重啟後仍使用已儲存的請求 ID,切換介面或語言也複用同一訂單。測試訪問令牌與 MochiPay 憑據獨立;正式接入時應替換為應用自身的使用者登入會話。

這些接入示例提供原始碼,不包含原生支付 SDK 或應用商店稽核許可。請按產品型別和目標地區檢視最新的 Apple 付款規則 與 Google Play 付款政策 。

上線前驗證

按各包中的 README 和 TESTING.md 驗證。本地簽名測試覆蓋重試、繫結不匹配、未付款及重複通知。仍需在測試環境完成 Xcode/Android Studio 真機驗收和小額真實付款。本次示例接入無需為 MochiPay 新增資料庫表或重灌外掛。

實現同步返回與非同步通知 →

返回與通知

使用同一套服務端校驗邏輯,處理 HPP 同步返回、HPP 非同步通知及 ON_SITE 非同步狀態更新。

統一核實付款,再更新本地訂單

流程API 欄位與入口用途
HPP 同步返回redirect_url · 瀏覽器 GET服務端簽名查詢後顯示結果。客戶可能不會返回此頁面。
HPP 非同步通知notify_url · 服務端 POST獨立核實並更新本地訂單,無需等待瀏覽器返回。
ON_SITE 非同步通知同一 notify_url · 服務端 POST即使付款彈窗或應用已關閉,仍可更新本地訂單。
ON_SITE 狀態顯示瀏覽器或應用輪詢商戶 /status顯示同一套後端校驗產生的必要結果。

HPP:瀏覽器同步返回

建立付款時,將本地訂單的訪問令牌放入 redirect_url 並儲存。示例使用商戶 HTTPS 地址 /complete?r=…&t=…。託管結賬結束後,瀏覽器返回此入口。讀取已儲存的本地訂單並校驗歸屬和令牌,再使用已儲存的 MochiPay order_id 簽名查詢訂單。

只有訂單繫結和實際收款金額校驗透過後,才能顯示 PAID;否則顯示等待或待核查。URL 標記、瀏覽器訊息或截圖不能證明付款成功。回撥可能早於或晚於瀏覽器返回。

HPP 與 ON_SITE:服務端非同步通知

建立時儲存 notify_url,示例使用 /callback?r=…&t=…。MochiPay 獨立於客戶瀏覽器向此地址傳送 POST。傳入欄位僅用於查詢訂單,不作為付款證明。透過已認證 API 查詢,並核對已儲存的 ID、商戶訂單號、原始金額與幣種、資產與網路、地址及精確應付金額。

要求來自該經過身份驗證的查詢的 PAID、正 應收/實收 金額以及完全相等或嚴格布爾值 manual_payment_accepted=true。原子記錄一次已驗證的本地付款;重複驗證的通知返回OK,無需更新或傳遞兩次。未經確認的狀態、無效綁定和 上游服務/儲存 失敗不得被確認為成功支付。

示例儲存一次性的 paid_verified 標記,不執行商品交付。正式接入應替換為自己訂單資料庫中的事務操作,僅憑回撥內容不能更新訂單。

ON_SITE:非同步更新與彈窗輪詢

ON_SITE 使用同一 notify_url,彈窗關閉或應用離線後仍會繼續核實付款。彈窗顯示期間每 15 秒只輪詢商戶已授權的後端,由後端查詢 MochiPay 並返回必要欄位,金額保留為十進位制字串。PAID 顯示與回撥使用同一套校驗邏輯;API Secret 和完整客戶資訊不進入瀏覽器。

關閉、重新開啟或切換 ON_SITE/HPP 時,複用同一筆已儲存付款。超時後保留 request_id 和原始建立請求,修改商戶訂單號可能造成額外開單。

各服務端包中的可執行程式碼

各示例包含兩種介面模式、通知處理、返回頁、安全的狀態介面及持久化的付款嘗試記錄。API 使用 notify_url 和 redirect_url;結賬模式由本地接入選擇,不是 Create Order 引數。

Node.js · 核實付款、返回與通知

以下節選自可執行示例包。介面變數和儲存輔助函式在完整原始碼中定義,接入時請使用完整實現。

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 · 核實付款、返回與通知

以下節選自可執行示例包。介面變數和儲存輔助函式在完整原始碼中定義,接入時請使用完整實現。

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 · 核實付款、返回與通知

以下節選自可執行示例包。介面變數和儲存輔助函式在完整原始碼中定義,接入時請使用完整實現。

        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 · 核實付款、返回與通知

以下節選自可執行示例包。介面變數和儲存輔助函式在完整原始碼中定義,接入時請使用完整實現。

    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 · 核實付款、返回與通知

以下節選自可執行示例包。介面變數和儲存輔助函式在完整原始碼中定義,接入時請使用完整實現。

    // 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 (!MochiPayPortable::paidAmountAccepted($order)) 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']);
}
下載完整示例

錯誤響應

錯誤返回 HTTP 狀態碼及穩定、可供程式識別的訊息。

JSON
{ "success": false, "message": "INVALID_SIGNATURE" }
HTTP訊息說明
400INVALID_JSON / INVALID_AMOUNT請求資料無效。
400CURRENCY_REQUIRED / CURRENCY_TOO_LONG請求資料無效。
400INVALID_UNIQUE_AMOUNT_DIRECTION / INVALID_PRODUCT_TYPE不支援此方向或商品型別值。
400FIELD_TOO_LONG / INVALID_REDIRECT_URL / INVALID_NOTIFY_URL可選欄位超過長度限制,或提供的 URL 無效。
400ORDER_ID_REQUIRED / ORDER_IDENTIFIER_CONFLICT缺少查詢標識,或標識相互衝突。
401INVALID_API_KEY / INVALID_SIGNATURE身份驗證失敗。
403SUBSCRIPTION_REQUIRED / SUBSCRIPTION_EXPIRED商戶訂閱當前不可用。
403MERCHANT_DISABLED商戶賬戶已禁用。
404ORDER_NOT_FOUND沒有找到屬於此商戶的匹配訂單。
500SYSTEM_ERROR請求未能完成。

經典 SaaS 串接

Shopyy / Shopoem、Shoplus、Wooshoppaas 與 Fecify 僅相容 HPP,無需下載外掛或修改 SaaS 原始碼。

模式 1:固定幣種與網路

帶 /{PaymentMethod} 時,客戶直接進入指定幣種與網路的掃碼付款頁。

POSThttps://mochi.bz/api/v/orders/legacy_create/YOUR_API_KEY/USDT_TRC20

模式 2:在收銀台選擇

客戶到 MochiPay 收銀台選擇付款幣種與網路,再產生 QR 碼付款。

POSThttps://mochi.bz/api/v/orders/legacy_create/YOUR_API_KEY

兩種模式沿用相同的 POST 參數、回傳格式與回呼流程。

URL 中使用 API Key,絕不能使用 API Secret。

支援的平臺

Shopyy / Shopoem同一公司,相容的閘道器格式
Shoplus配置支付介面 URL
Wooshoppaas配置支付介面 URL
Fecify配置支付介面 URL

設定

  1. 從 MochiPay 商戶後臺複製商戶 API Key。
  2. 將完整 URL 貼上到 SaaS 閘道器的介面或提交 URL 設定。
  3. 保留 SaaS 平臺已有 POST 引數、返回 URL 與通知 URL。

URL 示例

舊版支付介面 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

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

支付方式

USDT_TRC20USDT 上 TRON
USDC_ERC20在伊特魯姆的USDC
BTC_BITCOINBitcoin 網路原生 BTC
ETH_ERC20Ethereum 網路原生 ETH
SOL_SOLANASolana 網路原生 SOL
TRX_TRONTRON 網路原生 TRX

舊版必填欄位

引數用途
merchant_url原 SaaS 商城值,保留在完整請求記錄中以便診斷。
system_name已有 SaaS 平臺標識,會保留在完整請求記錄中。
account_type / payment_mode保留平臺原有值,通常為 live 與 sale.
orders_id原 SaaS 訂單標識。
amount / currency原始訂單金額與幣種。
return_url確認付款後的客戶返回 URL。
notify_url付款完成後的伺服器通知 URL。
securityToken可選透傳標記,將原樣返回。
products可選商品或購物車資料。
customer_*現有客戶、地址、IP 與 User-Agent 欄位。

建立訂單響應

現有 SaaS 接入從三段式純文字響應中提取託管結賬 URL。

文字
_____https://mochi.bz/pay/ORDER_ID_____

成功返回與通知欄位

領域值
securityToken原樣透傳的原始值。
paymentMethodonlinepay
paymentStatusCompleted
paymentTransaction已確認的區塊鏈交易雜湊。
paymentCommentsMochiPay payment confirmed
orderID原有 SaaS 的 orders_id.

電商外掛下載

透過對應平臺擴充套件將 MochiPay 接入獨立商城。請選擇平臺和版本分支。19 個下載包均為獨立 ZIP,內含英文說明和 PHP 要求,請使用準確商城版本允許的 PHP 環境。

站內支付 + HPP

WooCommerce

經典結賬、Checkout Blocks 和 HPOS。

平臺WooCommerce 5.8 或更高版本,使用原生閘道器 API
PHPPHP 7.4–8.4

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

OpenCart 2.0–2.2

早期支付路由與版本特定的模板路徑。

平臺OpenCart 2.0.x-2.2.x
PHPPHP 5.6–7.4;更高版本需要商城核心補丁

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

OpenCart 2.3

獨立的 2.3 擴充套件 / 支付目錄結構。

平臺OpenCart 2.3.x
PHPPHP 5.6–7.4;更高版本需要商城核心補丁

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

OpenCart 3

Twig 檢視與 OpenCart 3 原生支付閘道器。

平臺OpenCart 3.0.x
PHPPHP 5.6–8.4,並遵循確切的核心 / 依賴要求

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

OpenCart 4

原生 4.x 名稱空間、路由與擴充套件包結構。

平臺OpenCart 4.0.2.x-4.1.x
PHPPHP 8.0.2–8.4;4.1.0.4 需要 8.1+

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Zen Cart 1.5.3–1.5.7

舊版 define 語言檔案與原生狀態設定。

平臺Zen Cart 1.5.3-1.5.7
PHPPHP 5.6–8.0,取決於商城核心版本

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Zen Cart 1.5.8–2.2

現代陣列式語言檔案與原生狀態設定。

平臺Zen Cart 1.5.8 / 2.0.x / 2.1.x / 2.2.x
PHPPHP 7.3–8.4,取決於商城核心版本

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Magento 1 / OpenMage

Magento CE 1.9.3.0–1.9.4.5,以及相容的 OpenMage 19/20。

平臺Magento CE 1.9.3.0–1.9.4.5;OpenMage 19/20 原生 M1 API
PHPPHP 5.6–8.4;PHP 8 需要相容的 OpenMage 核心

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Magento 2

Magento Open Source 2.3.7–2.4.8,使用原生結賬。

平臺Magento Open Source 2.3.7–2.4.8,使用原生結賬
PHPPHP 7.3–8.4,取決於商城核心版本

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

PrestaShop 1.6

PrestaShop 1.6.1 支付鉤子與提交表單。

平臺PrestaShop 1.6.1.x
PHPPHP 5.6–7.1

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

PrestaShop 1.7 / 8 / 9

PrestaShop 1.7.6–1.7.8、8.x 和 9.0.x 的 paymentOptions。

平臺PrestaShop 1.7.6-1.7.8 / 8.x / 9.0.x
PHPPHP 5.6–8.4,取決於商城核心版本

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Shopware 6.6

Shopware 6.6 和 6.7 分別使用對應的原生處理器。

平臺Shopware >=6.6.10.0 <6.7.0.0
PHPPHP 8.2.x / 8.3.x / 8.4.x

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Shopware 6.7

Shopware 6.6 和 6.7 分別使用對應的原生處理器。

平臺Shopware >=6.7.0.0 <6.8.0.0
PHPPHP 8.2.x / 8.3.x / 8.4.x

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Drupal Commerce

適用於指定 Drupal 和 Commerce 分支的原生支付閘道器。

平臺商業 2.40.x 與 Drupal 9.3–10.x;或商業 3.3.10+ <3.4 和 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;以實際 Drupal 版本允許的環境為準

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

EC-CUBE 4.3

透過 EC-CUBE 原生購買流程處理日元結賬。

平臺EC-CUBE >=4.3.0 <4.4.0
PHPPHP 8.1.x / 8.2.x / 8.3.x

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Bagisto 2.3

透過 Laravel 擴充套件包處理原生訂單與發票。

平臺Bagisto >=2.3.0 <2.4.0
PHPPHP 8.2.x / 8.3.x / 8.4.x(同時滿足商城依賴鎖檔案的要求)

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

Sylius 2.0

接入原生 Payum 結賬和 Sylius 支付狀態機。

平臺Sylius >=2.0.0 <2.1.0,搭配 PayumBundle 2.6+ / 相容 Payum 1.7 的核心
PHPPHP 8.2.x / 8.3.x / 8.4.x(同時滿足商城依賴鎖檔案的要求)

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

osCommerce 4.14

原生 V4 支付模組,不適用於早期 osCommerce 2.x 和 3.x。

平臺osCommerce 4.14.x;原生 V4 orderPayment 模組介面
PHPPHP 7.4.x–8.3.x,以已安裝的 osCommerce 版本和依賴鎖檔案為準

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →
站內支付 + HPP

thirty bees 1.6

適用於 thirty bees 1.6 的原生支付模組與訂單歷史。

平臺thirty bees >=1.6.0 <1.7.0
PHPPHP 7.4.x / 8.0.x / 8.1.x / 8.2.x / 8.3.x;請使用對應的 thirty bees 發行包

英文安裝說明與詳細 PHP 環境表位於 ZIP 內。

下載 ZIP設定指南 →

新增介面卡為初始接入版本。正式啟用前,請在自己的測試商城完成安裝和真實付款驗收。

開始使用 MochiPay 開發

建立 MochiPay 賬戶,選擇適合付款流程的接入方式。

開始使用