概述

PayHydro 是一个代理收款服务,让您无需直接对接微信支付,即可在自己的应用中实现收款功能。

核心优势
  • 无需申请微信支付商户号
  • 简单的 RESTful API
  • 支持 Native 扫码支付
  • 自动支付结果回调

工作流程

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  您的网站    │────▶│  PayHydro   │────▶│   微信支付   │
│  (调用API)   │◀────│  (代理服务)  │◀────│   (处理)    │
└─────────────┘     └─────────────┘     └─────────────┘
       │                   │
       │   ④ 回调通知      │
       │◀──────────────────│
       │                   │

① 您的网站调用 PayHydro API 创建订单
② PayHydro 调用微信支付创建预付单
③ 用户扫码完成支付
④ PayHydro 收到微信回调后,通知您的网站

快速接入

获取 API Key

登录 管理后台,创建产品并生成 API Key。

重要
请妥善保管 API Key,它是调用接口的唯一凭证。Key 只在创建时显示一次!

配置回调地址

在管理后台编辑 API Key,设置您的回调通知地址。支付成功后,PayHydro 会向此地址 POST 支付结果。

示例: https://your-site.com/payment/callback

调用 API 创建订单

curl -X POST https://pay.hydrocoder.com/api/v1/pay/create \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "amount": 100,
    "description": "商品名称"
  }'

展示支付二维码

API 返回的 qrcode 字段是 Base64 编码的二维码图片,直接在页面展示即可。

<img src="${response.qrcode}" alt="扫码支付">

处理支付回调

用户支付成功后,PayHydro 会向您配置的回调地址发送 POST 请求,处理完成后返回 {"success": true}

身份认证

所有 API 请求都需要携带 API Key 进行身份验证。支持以下方式:

方式一:HTTP Header(推荐)

X-API-Key: your_api_key_here

方式二:URL 参数

https://pay.hydrocoder.com/api/v1/pay/create?key=your_api_key_here

方式三:请求体

{
    "key": "your_api_key_here",
    "amount": 100,
    ...
}

跳转支付

最简单的接入方式!只需构造一个链接,用户点击后跳转到 PayHydro 完成支付,支付完成后自动跳回您的网站。

适用场景
  • 无后端开发能力的静态网站
  • 想快速集成支付功能
  • 不想处理 OAuth 授权流程

使用方法

构造以下格式的 URL,让用户在微信内打开即可:

GET /pay/gateway

URL 参数

参数类型必填说明
keystring您的 API Key
amountint金额,单位:分。如 100 表示 1.00 元
descriptionstring商品描述
attachstring附加数据,支付成功后原样返回
return_urlstring支付完成后跳转地址

完整示例

https://pay.hydrocoder.com/pay/gateway?key=YOUR_API_KEY&amount=100&description=商品名称&return_url=https://your-site.com/success

HTML 接入示例

<!-- 最简单的接入方式:一个链接即可 -->
<a href="https://pay.hydrocoder.com/pay/gateway?key=YOUR_KEY&amount=100&description=VIP会员">
    立即支付 ¥1.00
</a>

<!-- 或者用按钮 -->
<button onclick="location.href='https://pay.hydrocoder.com/pay/gateway?key=YOUR_KEY&amount=100'">
    微信支付
</button>

JavaScript 动态生成

function pay(amount, description) {
    const params = new URLSearchParams({
        key: 'YOUR_API_KEY',
        amount: amount * 100,  // 转换为分
        description: description,
        return_url: window.location.origin + '/pay-success'
    });

    // 跳转到支付页面
    window.location.href = 'https://pay.hydrocoder.com/pay/gateway?' + params;
}

// 使用:支付 9.9 元
pay(9.9, 'VIP月卡');

支付完成后的跳转

支付完成后,用户会被跳转到您设置的 return_url,并附带以下参数:

https://your-site.com/success?order_no=PH20251221xxx&status=success
参数说明
order_noPayHydro 订单号
status支付状态:success 或 fail
重要提示
  • 跳转支付使用的是 JSAPI 支付,必须在微信内打开链接才能支付
  • return_url 的跳转只是前端跳转,不能作为支付成功的凭证
  • 请务必配置回调地址,通过后端回调来确认支付结果

API 创建订单

POST /api/v1/pay/create

请求参数

参数类型必填说明
amountint金额,单位:分。如 100 表示 1.00 元
descriptionstring商品描述,默认使用产品名称
notify_urlstring回调地址,默认使用 Key 配置的地址
attachstring附加数据,支付成功后原样返回
pay_typestring支付方式:native(默认) 或 jsapi
openidstring条件用户 OpenID,pay_type=jsapi 时必填

返回示例

{
    "success": true,
    "order_no": "PH20251221123456ABCD",
    "amount": 100,
    "pay_type": "native",
    "code_url": "weixin://wxpay/bizpayurl?pr=xxxx",
    "qrcode": "data:image/png;base64,iVBORw0KGgo..."
}

返回字段说明

字段说明
success是否成功
order_noPayHydro 订单号
amount订单金额(分)
code_url微信支付链接(可自行生成二维码)
qrcode二维码图片 Base64(可直接用于 img src)

查询订单

GET /api/v1/pay/query

请求参数

参数类型必填说明
order_nostring订单号

返回示例

{
    "success": true,
    "order": {
        "order_no": "PH20251221123456ABCD",
        "amount": 100,
        "status": "paid",
        "description": "测试商品",
        "transaction_id": "420000292922...",
        "paid_at": "2025-12-21 10:30:00",
        "created_at": "2025-12-21 10:25:00"
    }
}

订单状态

状态说明
pending待支付
paid已支付
closed已关闭
refunded已退款

关闭订单

POST /api/v1/pay/close

请求参数

参数类型必填说明
order_nostring订单号

返回示例

{
    "success": true,
    "message": "Order closed"
}
注意
只能关闭状态为 pending 的订单,已支付的订单无法关闭。

订单列表

GET /api/v1/orders

请求参数

参数类型必填说明
pageint页码,默认 1
per_pageint每页数量,默认 20,最大 100
statusstring状态筛选

返回示例

{
    "success": true,
    "orders": [...],
    "total": 100,
    "page": 1,
    "per_page": 20,
    "pages": 5
}

回调通知

用户支付成功后,PayHydro 会向您配置的回调地址发送 HTTP POST 请求。

回调数据格式

{
    "order_no": "PH20251221123456ABCD",
    "amount": 100,
    "status": "paid",
    "transaction_id": "4200002929222025122165024151",
    "paid_at": "2025-12-21 10:30:00",
    "attach": "user_id=123&product_id=456"
}

字段说明

字段说明
order_noPayHydro 订单号
amount支付金额(分)
status订单状态,固定为 paid
transaction_id微信支付交易号
paid_at支付时间
attach创建订单时传入的附加数据
回调要求
  • 您的服务器需要返回 HTTP 200 状态码
  • 响应内容建议为 {"success": true}
  • 回调超时时间为 10 秒

回调处理建议

重要:防止重复处理
由于网络等原因,回调可能会重复发送。请务必根据 order_no 做幂等处理,避免重复发货或重复充值。

推荐处理流程

def handle_callback(data):
    order_no = data['order_no']

    # 1. 查询本地订单
    order = db.query("SELECT * FROM orders WHERE pay_order_no = ?", order_no)

    # 2. 检查是否已处理(幂等)
    if order and order.status == 'paid':
        return {"success": True}  # 已处理过,直接返回成功

    # 3. 验证金额是否匹配
    if order.amount != data['amount']:
        log.error("金额不匹配!")
        return {"success": False}

    # 4. 更新订单状态
    db.execute("UPDATE orders SET status='paid', paid_at=? WHERE id=?",
               data['paid_at'], order.id)

    # 5. 执行业务逻辑(发货、充值等)
    do_business_logic(order)

    return {"success": True}

Python 示例

安装依赖

pip install requests flask

创建订单

import requests

API_KEY = "your_api_key_here"
API_URL = "https://pay.hydrocoder.com/api/v1"

def create_order(amount, description="商品", attach=""):
    """创建收款订单"""
    response = requests.post(
        f"{API_URL}/pay/create",
        json={
            "amount": amount,  # 金额(分)
            "description": description,
            "attach": attach
        },
        headers={
            "X-API-Key": API_KEY,
            "Content-Type": "application/json"
        }
    )
    return response.json()

# 创建 1 元的订单
result = create_order(100, "测试商品", "user_id=123")
if result['success']:
    print(f"订单号: {result['order_no']}")
    print(f"二维码: {result['qrcode']}")
else:
    print(f"失败: {result['error']}")

接收回调 (Flask)

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/payment/callback', methods=['POST'])
def payment_callback():
    """接收支付回调"""
    data = request.get_json()

    order_no = data['order_no']
    amount = data['amount']
    status = data['status']
    attach = data.get('attach', '')

    print(f"收到支付通知: 订单={order_no}, 金额={amount/100}元")

    # TODO: 更新您的订单状态,执行发货等业务逻辑
    # 注意:要做幂等处理,防止重复发货

    return jsonify({"success": True})

if __name__ == '__main__':
    app.run(port=8080)

PHP 示例

创建订单

<?php
$api_key = "your_api_key_here";
$api_url = "https://pay.hydrocoder.com/api/v1/pay/create";

function create_order($amount, $description = "商品", $attach = "") {
    global $api_key, $api_url;

    $data = json_encode([
        "amount" => $amount,
        "description" => $description,
        "attach" => $attach
    ]);

    $ch = curl_init($api_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Content-Type: application/json",
        "X-API-Key: " . $api_key
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

// 创建 1 元的订单
$result = create_order(100, "测试商品", "user_id=123");
if ($result['success']) {
    echo "订单号: " . $result['order_no'] . "\n";
    echo "<img src='" . $result['qrcode'] . "'>";
} else {
    echo "失败: " . $result['error'];
}
?>

接收回调

<?php
// callback.php - 接收支付回调

$json = file_get_contents('php://input');
$data = json_decode($json, true);

$order_no = $data['order_no'];
$amount = $data['amount'];
$status = $data['status'];
$attach = $data['attach'] ?? '';

// 记录日志
error_log("收到支付回调: order_no=$order_no, amount=$amount, status=$status");

// TODO: 更新订单状态,执行业务逻辑
// 注意幂等处理!

// 返回成功
header('Content-Type: application/json');
echo json_encode(['success' => true]);
?>

Node.js 示例

安装依赖

npm install axios express

创建订单

const axios = require('axios');

const API_KEY = 'your_api_key_here';
const API_URL = 'https://pay.hydrocoder.com/api/v1';

async function createOrder(amount, description = '商品', attach = '') {
    const response = await axios.post(
        `${API_URL}/pay/create`,
        { amount, description, attach },
        {
            headers: {
                'X-API-Key': API_KEY,
                'Content-Type': 'application/json'
            }
        }
    );
    return response.data;
}

// 创建 1 元的订单
createOrder(100, '测试商品', 'user_id=123')
    .then(result => {
        if (result.success) {
            console.log('订单号:', result.order_no);
            console.log('二维码:', result.qrcode);
        } else {
            console.log('失败:', result.error);
        }
    });

接收回调 (Express)

const express = require('express');
const app = express();

app.use(express.json());

app.post('/payment/callback', (req, res) => {
    const { order_no, amount, status, attach } = req.body;

    console.log(`收到支付通知: 订单=${order_no}, 金额=${amount/100}元`);

    // TODO: 更新订单状态,执行业务逻辑

    res.json({ success: true });
});

app.listen(8080, () => {
    console.log('服务器运行在 http://localhost:8080');
});

Java 示例

创建订单 (使用 OkHttp)

import okhttp3.*;
import org.json.JSONObject;

public class PayHydroClient {
    private static final String API_KEY = "your_api_key_here";
    private static final String API_URL = "https://pay.hydrocoder.com/api/v1";
    private static final OkHttpClient client = new OkHttpClient();

    public static JSONObject createOrder(int amount, String description, String attach)
            throws Exception {
        JSONObject json = new JSONObject();
        json.put("amount", amount);
        json.put("description", description);
        json.put("attach", attach);

        RequestBody body = RequestBody.create(
            json.toString(),
            MediaType.parse("application/json")
        );

        Request request = new Request.Builder()
            .url(API_URL + "/pay/create")
            .addHeader("X-API-Key", API_KEY)
            .post(body)
            .build();

        try (Response response = client.newCall(request).execute()) {
            return new JSONObject(response.body().string());
        }
    }

    public static void main(String[] args) throws Exception {
        JSONObject result = createOrder(100, "测试商品", "user_id=123");
        if (result.getBoolean("success")) {
            System.out.println("订单号: " + result.getString("order_no"));
        }
    }
}

接收回调 (Spring Boot)

@RestController
public class PaymentController {

    @PostMapping("/payment/callback")
    public Map<String, Object> callback(@RequestBody Map<String, Object> data) {
        String orderNo = (String) data.get("order_no");
        Integer amount = (Integer) data.get("amount");
        String status = (String) data.get("status");

        System.out.println("收到支付通知: 订单=" + orderNo + ", 金额=" + amount/100.0 + "元");

        // TODO: 更新订单状态,执行业务逻辑

        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        return response;
    }
}

错误码

HTTP 状态码错误信息说明
401Missing API Key未提供 API Key
401Invalid API KeyAPI Key 无效或已禁用
403Product disabled产品已禁用
400Invalid amount金额无效
400JSAPI requires openidJSAPI 支付需要 openid
404Order not found订单不存在
403Permission denied无权操作此订单
500Payment service unavailable支付服务不可用

常见问题

Q: 回调地址必须是公网可访问的吗?

是的。PayHydro 服务器需要能够访问您的回调地址。本地开发时可以使用内网穿透工具(如 ngrok、frp)。

Q: 如何测试回调?

可以使用 Demo 页面 进行测试。创建订单时会自动使用 demo 回调地址,支付成功后可以在页面上看到回调数据。

Q: 金额单位是什么?

金额单位是。例如:100 表示 1.00 元,1 表示 0.01 元。

Q: attach 字段有什么用?

attach 是附加数据,创建订单时传入,支付成功回调时会原样返回。常用于传递用户ID、订单ID等业务数据。

Q: 订单多久会过期?

微信支付订单有效期为 2 小时,超时未支付会自动关闭。

Q: 支持退款吗?

目前暂不支持 API 退款,如需退款请联系管理员在微信商户后台操作。

PayHydro - 简单易用的代理收款服务

管理后台 · 在线演示