概述
PayHydro 是一个代理收款服务,让您无需直接对接微信支付,即可在自己的应用中实现收款功能。
- 无需申请微信支付商户号
- 简单的 RESTful API
- 支持 Native 扫码支付
- 自动支付结果回调
工作流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 您的网站 │────▶│ PayHydro │────▶│ 微信支付 │
│ (调用API) │◀────│ (代理服务) │◀────│ (处理) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ ④ 回调通知 │
│◀──────────────────│
│ │
① 您的网站调用 PayHydro API 创建订单
② PayHydro 调用微信支付创建预付单
③ 用户扫码完成支付
④ PayHydro 收到微信回调后,通知您的网站
快速接入
配置回调地址
在管理后台编辑 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,让用户在微信内打开即可:
URL 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 您的 API Key |
| amount | int | 是 | 金额,单位:分。如 100 表示 1.00 元 |
| description | string | 否 | 商品描述 |
| attach | string | 否 | 附加数据,支付成功后原样返回 |
| return_url | string | 否 | 支付完成后跳转地址 |
完整示例
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_no | PayHydro 订单号 |
| status | 支付状态:success 或 fail |
- 跳转支付使用的是 JSAPI 支付,必须在微信内打开链接才能支付
- return_url 的跳转只是前端跳转,不能作为支付成功的凭证
- 请务必配置回调地址,通过后端回调来确认支付结果
API 创建订单
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| amount | int | 是 | 金额,单位:分。如 100 表示 1.00 元 |
| description | string | 否 | 商品描述,默认使用产品名称 |
| notify_url | string | 否 | 回调地址,默认使用 Key 配置的地址 |
| attach | string | 否 | 附加数据,支付成功后原样返回 |
| pay_type | string | 否 | 支付方式:native(默认) 或 jsapi |
| openid | string | 条件 | 用户 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_no | PayHydro 订单号 |
| amount | 订单金额(分) |
| code_url | 微信支付链接(可自行生成二维码) |
| qrcode | 二维码图片 Base64(可直接用于 img src) |
查询订单
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_no | string | 是 | 订单号 |
返回示例
{
"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 | 已退款 |
关闭订单
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_no | string | 是 | 订单号 |
返回示例
{
"success": true,
"message": "Order closed"
}
订单列表
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | int | 否 | 页码,默认 1 |
| per_page | int | 否 | 每页数量,默认 20,最大 100 |
| status | string | 否 | 状态筛选 |
返回示例
{
"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_no | PayHydro 订单号 |
| amount | 支付金额(分) |
| status | 订单状态,固定为 paid |
| transaction_id | 微信支付交易号 |
| paid_at | 支付时间 |
| attach | 创建订单时传入的附加数据 |
- 您的服务器需要返回 HTTP 200 状态码
- 响应内容建议为
{"success": true} - 回调超时时间为 10 秒
回调处理建议
推荐处理流程
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 状态码 | 错误信息 | 说明 |
|---|---|---|
| 401 | Missing API Key | 未提供 API Key |
| 401 | Invalid API Key | API Key 无效或已禁用 |
| 403 | Product disabled | 产品已禁用 |
| 400 | Invalid amount | 金额无效 |
| 400 | JSAPI requires openid | JSAPI 支付需要 openid |
| 404 | Order not found | 订单不存在 |
| 403 | Permission denied | 无权操作此订单 |
| 500 | Payment 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 退款,如需退款请联系管理员在微信商户后台操作。