安全提示:本平台是支付机构代理商,不涉及资金清算,不触碰用户资金。资金由持牌支付机构与您直接清算,望知晓!

协议规则

请求数据格式application/x-www-form-urlencoded
返回数据格式JSON
签名算法MD5(结果为32位小写)
字符编码UTF-8

接入安全须知(必读)

1、回调必须验签:收到异步通知先校验 sign,不一致直接丢弃,不做任何入账处理。

2、入账必须二次确认:验签通过后,务必再调用查询单个订单接口,返回 status=1(已支付)才允许入账。回调只能当提醒,不能当支付凭证。

3、金额/单号比对:回调 money 必须等于你下单时的金额;同一 out_trade_no 只允许入账一次(幂等)。

4、通知送达确认:处理成功后必须输出 success 字样,平台才会停止重试;验签失败请勿返回 success。

5、密钥保密:商户密钥只存放于服务端,严禁出现在URL、前端页面或日志中;一旦疑似泄露,请立即登录商户后台重置密钥。

测试账号

商户ID(PID):1003

商户密钥(KEY):fnv5Xf0BnV5n5bGzFf7V7Fvn9tVtzn9v

说明:

1、测试金额应为小额,建议单笔测试交易 0.01 元以内;

2、测试交易完成后,如需退款应当日(通过 API 提交订单退款);

3、测试账号仅供测试使用,请勿用在自己正式运营的网站上;

4、本平台兼容易支付接口,无需额外开发,可直接使用。

API接口统一下单支付(推荐)

此接口可用于服务器后端发起支付请求,会返回支付跳转url。(此url是自适应页面,包含手机端H5唤起支付、PC端扫码支付、微信内支付等等。例如:付款方如果在手机浏览器打开这个URL是H5唤起支付,如果在PC电脑端打开这个URL是PC扫码支付,如果在APP内打开是APP支付)

URL地址:https://api.payqixiang.cn/mapi.php(设置为可配置的变量,以便接口变更时方便修改)

请求方式:POST

注:1、实际要以ASCII码从小到大排序,具体详细请查看下方 MD5签名算法;

注:2、若使用POST报错,请用GET测试。

请求参数说明:

字段名变量名必填类型示例值描述
商户IDpid是Int1001
支付方式type是Stringalipayalipay:支付宝,wxpay:微信支付
商户订单号out_trade_no是String20160806151343349此单号对应的支付方式是唯一的,也就是微信一套单号、支付宝一套单号,万不可混用
异步通知地址notify_url是Stringhttp://www.pay.com/notify_url.php服务器异步通知地址,支付结果通知
跳转通知地址return_url是Stringhttp://www.pay.com/return_url.php页面跳转通知地址
商品名称name是StringVIP会员如超过127个字节会自动截取
商品金额money是String1.00单位:元,最大2位小数
用户IP地址clientip是String192.168.1.100不强求真实,可随意传入一个IP
设备类型device是Stringjump根据传入的设备类型参数判断返回的是二维码链接或其它支付跳转URL等,设备类型列表
业务扩展参数param否String没有请留空支付后原样返回
签名字符串sign是String202cb962ac59075b964b07152d234b70签名算法点此查看
签名类型sign_type是StringMD5默认为MD5

返回结果(json):

字段名变量名类型示例值描述
返回状态码codeInt11为成功,其它值为失败
返回信息msgString失败时返回原因
订单号trade_noString20160806151343349支付订单号
支付跳转URLpayurlStringhttps://api.payqixiang.cn/pay/submit/202312311388/直接获取json返回值,引导客户跳转到该url支付链接支付
二维码链接qrcodeString默认:https://api.payqixiang.cn/pay/wxjspay/
原生:weixin://wxpay/bizpayurl?pr=l1zE22Nz3
如果返回该字段,则根据该url自行生成二维码
JSON下单成功返回示例
{
    "code": 1,
    "msg": "",
    "trade_no": "20260806151343349",
    "payurl": "https://api.payqixiang.cn/pay/submit/202312311388/",
    "qrcode": ""
}
发起支付请求示例(含签名生成)
<?php
// ===== 商户配置 =====
$pid = '1001';                                // 商户ID
$key = '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i';   // 商户密钥
$api = 'https://api.payqixiang.cn/mapi.php'; // 支付网关地址(建议设置为可配置变量)

// ===== 请求参数 =====
$data = array(
    'pid'          => $pid,
    'type'         => 'alipay',                // 支付方式:alipay 支付宝 / wxpay 微信支付
    'out_trade_no' => date('YmdHis') . rand(1000, 9999), // 商户订单号,需保证唯一
    'notify_url'   => 'https://www.example.com/notify_url.php', // 异步通知地址
    'return_url'   => 'https://www.example.com/return_url.php', // 页面跳转通知地址
    'name'         => 'VIP会员',               // 商品名称
    'money'        => '1.00',                 // 商品金额,单位:元,最大2位小数
    'clientip'     => '192.168.1.100',        // 用户IP,不强求真实
    'device'       => 'jump',                 // 设备类型:jump 返回自适应支付页(推荐)
);

// ===== 生成签名(详细算法见下方「MD5签名算法」)=====
unset($data['sign'], $data['sign_type']);
ksort($data);
$str = urldecode(http_build_query(array_filter($data, function ($v) { return $v !== '' && $v !== null; })));
$data['sign']      = md5($str . $key); // MD5 结果为32位小写
$data['sign_type'] = 'MD5';

// ===== 发起请求 =====
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

// ===== 处理返回结果 =====
$res = json_decode($result, true);
if (isset($res['code']) && $res['code'] == 1) {
    // 下单成功,引导用户跳转到支付链接
    header('Location: ' . $res['payurl']);
    exit;
} else {
    exit('下单失败:' . (isset($res['msg']) ? $res['msg'] : '未知错误'));
}
// 需引入 Hutool 工具库,Maven 依赖:cn.hutool:hutool-all
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;

import java.util.Map;
import java.util.TreeMap;

public class PayDemo {
    public static void main(String[] args) {
        String pid = "1001";                                // 商户ID
        String key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i";   // 商户密钥
        String api = "https://api.payqixiang.cn/mapi.php"; // 支付网关地址

        // 请求参数(TreeMap 自动按参数名 ASCII 码从小到大排序)
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("pid", pid);
        params.put("type", "alipay");                     // 支付方式:alipay / wxpay
        params.put("out_trade_no", "20260929123456789");  // 商户订单号,需保证唯一
        params.put("notify_url", "https://www.example.com/notify_url.php");
        params.put("return_url", "https://www.example.com/return_url.php");
        params.put("name", "VIP会员");                     // 商品名称
        params.put("money", "1.00");                      // 金额,单位:元,最大2位小数
        params.put("clientip", "192.168.1.100");
        params.put("device", "jump");                     // 设备类型:jump 返回自适应支付页(推荐)

        // 生成签名:拼接 a=b&c=d 后接商户密钥,MD5 为32位小写
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> e : params.entrySet()) {
            if (e.getValue() == null || e.getValue().toString().isEmpty()) continue;
            if (sb.length() > 0) sb.append('&');
            sb.append(e.getKey()).append('=').append(e.getValue());
        }
        params.put("sign", DigestUtil.md5Hex(sb.toString() + key));
        params.put("sign_type", "MD5");

        // 发起请求并获取返回 JSON
        String result = HttpRequest.post(api).form(params).execute().body();
        System.out.println(result);
        // 返回 JSON 中 code=1 表示成功,引导用户跳转 payurl 支付即可
    }
}
# pip install requests
import hashlib
import requests

# 商户配置
PID = '1001'
KEY = '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i'
API = 'https://api.payqixiang.cn/mapi.php'

# 请求参数
params = {
    'pid': PID,
    'type': 'alipay',                    # 支付方式:alipay / wxpay
    'out_trade_no': '20260929123456789', # 商户订单号,需保证唯一
    'notify_url': 'https://www.example.com/notify_url.php',
    'return_url': 'https://www.example.com/return_url.php',
    'name': 'VIP会员',                   # 商品名称
    'money': '1.00',                     # 金额,单位:元,最大2位小数
    'clientip': '192.168.1.100',
    'device': 'jump',                    # 设备类型:jump 返回自适应支付页(推荐)
}

# 生成签名:参数按 ASCII 码从小到大排序,拼接 a=b&c=d 后接商户密钥,MD5 为32位小写
query = '&'.join(f'{k}={params[k]}' for k in sorted(params) if params[k] not in ('', None))
params['sign'] = hashlib.md5((query + KEY).encode('utf-8')).hexdigest()
params['sign_type'] = 'MD5'

# 发起请求
res = requests.post(API, data=params).json()
if res.get('code') == 1:
    # 下单成功,引导用户跳转到支付链接
    print(res['payurl'])
else:
    print('下单失败:', res.get('msg'))
// Node.js 18+ 内置 fetch,无需额外依赖
const crypto = require('crypto');

// 商户配置
const PID = '1001';
const KEY = '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i';
const API = 'https://api.payqixiang.cn/mapi.php';

// 请求参数
const params = {
    pid: PID,
    type: 'alipay',                    // 支付方式:alipay / wxpay
    out_trade_no: '20260929123456789', // 商户订单号,需保证唯一
    notify_url: 'https://www.example.com/notify_url.php',
    return_url: 'https://www.example.com/return_url.php',
    name: 'VIP会员',                   // 商品名称
    money: '1.00',                     // 金额,单位:元,最大2位小数
    clientip: '192.168.1.100',
    device: 'jump',                    // 设备类型:jump 返回自适应支付页(推荐)
};

// 生成签名:参数按 ASCII 码从小到大排序,拼接 a=b&c=d 后接商户密钥,MD5 为32位小写
const query = Object.keys(params)
    .filter(k => params[k] !== '' && params[k] !== undefined)
    .sort()
    .map(k => `${k}=${params[k]}`)
    .join('&');
params.sign = crypto.createHash('md5').update(query + KEY).digest('hex');
params.sign_type = 'MD5';

// 发起请求
const res = await fetch(API, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams(params).toString(),
}).then(r => r.json());

if (res.code === 1) {
    // 下单成功,引导用户跳转到支付链接
    console.log(res.payurl);
} else {
    console.log('下单失败:', res.msg);
}
// Go 标准库示例,无需第三方依赖
package main

import (
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "sort"
    "strings"
)

func main() {
    // 商户配置
    key := "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"
    api := "https://api.payqixiang.cn/mapi.php"

    // 请求参数
    params := map[string]string{
        "pid":          "1001",              // 商户ID
        "type":         "alipay",            // 支付方式:alipay / wxpay
        "out_trade_no": "20260929123456789", // 商户订单号,需保证唯一
        "notify_url":   "https://www.example.com/notify_url.php",
        "return_url":   "https://www.example.com/return_url.php",
        "name":         "VIP会员",            // 商品名称
        "money":        "1.00",              // 金额,单位:元,最大2位小数
        "clientip":     "192.168.1.100",
        "device":       "jump",              // 设备类型:jump 返回自适应支付页(推荐)
    }

    // 生成签名:参数按 ASCII 升序拼接 a=b&c=d 后接商户密钥,MD5 为32位小写
    keys := make([]string, 0, len(params))
    for k, v := range params {
        if v != "" {
            keys = append(keys, k)
        }
    }
    sort.Strings(keys)
    pairs := make([]string, 0, len(keys))
    for _, k := range keys {
        pairs = append(pairs, k+"="+params[k])
    }
    sum := md5.Sum([]byte(strings.Join(pairs, "&") + key))
    params["sign"] = hex.EncodeToString(sum[:]) // 32位小写
    params["sign_type"] = "MD5"

    // 发起请求
    form := url.Values{}
    for k, v := range params {
        form.Set(k, v)
    }
    resp, err := http.PostForm(api, form)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    fmt.Println(string(body))
    // 返回 JSON 中 code=1 表示成功,引导用户跳转 payurl 支付即可
}
// .NET 6+ 示例,使用 HttpClient
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

var api = "https://api.payqixiang.cn/mapi.php";
var key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i";

// 请求参数
var data = new Dictionary<string, string>
{
    ["pid"] = "1001",                       // 商户ID
    ["type"] = "alipay",                    // 支付方式:alipay / wxpay
    ["out_trade_no"] = "20260929123456789", // 商户订单号,需保证唯一
    ["notify_url"] = "https://www.example.com/notify_url.php",
    ["return_url"] = "https://www.example.com/return_url.php",
    ["name"] = "VIP会员",                   // 商品名称
    ["money"] = "1.00",                     // 金额,单位:元,最大2位小数
    ["clientip"] = "192.168.1.100",
    ["device"] = "jump",                    // 设备类型:jump 返回自适应支付页(推荐)
};

// 生成签名:参数按 ASCII 升序拼接 a=b&c=d 后接商户密钥,MD5 为32位小写
var pairs = data.Where(p => !string.IsNullOrEmpty(p.Value))
    .OrderBy(p => p.Key, StringComparer.Ordinal)
    .Select(p => $"{p.Key}={p.Value}");
data["sign"] = Convert.ToHexString(
    MD5.HashData(Encoding.UTF8.GetBytes(string.Join("&", pairs) + key))).ToLower();
data["sign_type"] = "MD5";

// 发起请求
using var client = new HttpClient();
var resp = await client.PostAsync(api, new FormUrlEncodedContent(data));
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var json = doc.RootElement;
if (json.GetProperty("code").GetInt32() == 1)
{
    // 下单成功,引导用户跳转到支付链接
    Console.WriteLine(json.GetProperty("payurl").GetString());
}
else
{
    Console.WriteLine("下单失败:" + (json.TryGetProperty("msg", out var msg) ? msg.GetString() : "未知错误"));
}
// 安卓示例,需引入 OkHttp:implementation("com.squareup.okhttp3:okhttp:4.12.0")
// 网络请求需在子线程执行(如协程 withContext(Dispatchers.IO))
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import java.security.MessageDigest

fun createOrder() {
    val key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"
    val api = "https://api.payqixiang.cn/mapi.php"

    // 请求参数(sortedMapOf 保证参数按 ASCII 升序)
    val params = sortedMapOf(
        "pid" to "1001",                       // 商户ID
        "type" to "alipay",                    // 支付方式:alipay / wxpay
        "out_trade_no" to "20260929123456789", // 商户订单号,需保证唯一
        "notify_url" to "https://www.example.com/notify_url.php",
        "return_url" to "https://www.example.com/return_url.php",
        "name" to "VIP会员",                   // 商品名称
        "money" to "1.00",                     // 金额,单位:元,最大2位小数
        "clientip" to "192.168.1.100",
        "device" to "jump",                    // 设备类型:jump 返回自适应支付页(推荐)
    )

    // 生成签名:参数按 ASCII 升序拼接 a=b&c=d 后接商户密钥,MD5 为32位小写
    val query = params.entries.joinToString("&") { "${it.key}=${it.value}" }
    val sign = MessageDigest.getInstance("MD5").digest((query + key).toByteArray())
        .joinToString("") { "%02x".format(it) }
    params["sign"] = sign
    params["sign_type"] = "MD5"

    // 发起请求
    val form = FormBody.Builder().apply {
        params.forEach { (k, v) -> add(k, v) }
    }.build()
    val request = Request.Builder().url(api).post(form).build()
    val body = OkHttpClient().newCall(request).execute().body?.string()
    println(body) // 解析 JSON:code=1 表示成功,跳转 payurl 拉起支付
}
// iOS 示例(Swift 5+),使用 URLSession,无需第三方库
import Foundation
import CryptoKit

func createOrder() {
    let key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"
    let api = "https://api.payqixiang.cn/mapi.php"

    // 请求参数
    var params: [String: String] = [
        "pid": "1001",                       // 商户ID
        "type": "alipay",                    // 支付方式:alipay / wxpay
        "out_trade_no": "20260929123456789", // 商户订单号,需保证唯一
        "notify_url": "https://www.example.com/notify_url.php",
        "return_url": "https://www.example.com/return_url.php",
        "name": "VIP会员",                   // 商品名称
        "money": "1.00",                     // 金额,单位:元,最大2位小数
        "clientip": "192.168.1.100",
        "device": "jump",                    // 设备类型:jump 返回自适应支付页(推荐)
    ]

    // 生成签名:参数按 ASCII 升序拼接 a=b&c=d 后接商户密钥,MD5 为32位小写
    let query = params.filter { !$0.value.isEmpty }
        .sorted { $0.key < $1.key }
        .map { "\($0.key)=\($0.value)" }
        .joined(separator: "&")
    let digest = Insecure.MD5.hash(data: Data((query + key).utf8))
    params["sign"] = digest.map { String(format: "%02x", $0) }.joined()
    params["sign_type"] = "MD5"

    // 发起请求(POST form 表单)
    let form = params.map { "\($0.key)=\($0.value)" }.joined(separator: "&")
    var request = URLRequest(url: URL(string: api)!)
    request.httpMethod = "POST"
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpBody = form.data(using: .utf8)

    URLSession.shared.dataTask(with: request) { data, _, _ in
        guard let data = data,
              let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
              let code = json["code"] as? Int else { return }
        if code == 1, let payurl = json["payurl"] as? String {
            // 下单成功,跳转 payurl 拉起支付(UI 操作需回主线程)
            print(payurl)
        } else {
            print("下单失败:\(json["msg"] ?? "未知错误")")
        }
    }.resume()
}

注:返回的参数中到底是二维码链接还是支付跳转url,其实是根据你设备类型device传入的值来决定的。例如设备类型device参数值传入"pc"则只返回qrcode二维码链接,需自行包装转换成二维码。如果不懂怎么展示支付页面,可在设备类型device值中传入"jump",这样就只会返回支付跳转url,此url是自适应页面,包含手机端H5唤起支付、PC端扫码支付等,直接前台跳转到这个url链接支付即可。

2、如果对接过程中出现异步参数名被转义成"¬ify url"这样会导致接口报错,请自行百度解决;

3、APP对接的话微信支付需要在app内调用webview组件跳转支付链接,然后需要在webview中手动设置referer,如 (Map extraHeaders = new HashMap();extraHeaders.put("Referer", "https://api.payqixiang.cn")) 可直接吊起。支付宝不需要,直接webview组件跳转支付链接即可;

4、pc返回的二维码链接一般默认不是微信原生二维码链接及支付页面,若需原生链接页面请联系客服。

页面跳转支付

此接口可用于用户前台直接发起支付,使用form表单跳转或拼接成url跳转。

URL地址:https://api.payqixiang.cn/submit.php(设置为可配置的变量,以便接口变更时方便修改)

请求方式:POST

注:实际要以ASCII码从小到大排序,具体详细请查看下方 MD5签名算法。

请求参数说明:

字段名变量名必填类型示例值描述
商户IDpid是Int1001
支付方式type否Stringalipayalipay:支付宝,wxpay:微信支付
商户订单号out_trade_no是String20160806151343349
异步通知地址notify_url是Stringhttp://www.pay.com/notify_url.php服务器异步通知地址
跳转通知地址return_url是Stringhttp://www.pay.com/return_url.php页面跳转通知地址
商品名称name是StringVIP会员如超过127个字节会自动截取
商品金额money是String1.00单位:元,最大2位小数
业务扩展参数param否String没有请留空支付后原样返回
签名字符串sign是String202cb962ac59075b964b07152d234b70签名算法点此查看
签名类型sign_type是StringMD5默认为MD5
HTMLform表单自动提交跳转支付示例
<!-- sign 需在服务器端按「MD5签名算法」生成后再输出到表单,不可在前端计算 -->
<form id="payform" action="https://api.payqixiang.cn/submit.php" method="post">
    <input type="hidden" name="pid"          value="1001" />
    <input type="hidden" name="type"         value="alipay" />
    <input type="hidden" name="out_trade_no" value="20260929123456789" />
    <input type="hidden" name="notify_url"   value="https://www.example.com/notify_url.php" />
    <input type="hidden" name="return_url"   value="https://www.example.com/return_url.php" />
    <input type="hidden" name="name"         value="VIP会员" />
    <input type="hidden" name="money"        value="1.00" />
    <input type="hidden" name="sign"         value="127d5a7f5d5a5b1c9f3c1f8f8c8c8a8a" />
    <input type="hidden" name="sign_type"    value="MD5" />
</form>
<script>document.getElementById('payform').submit();</script>

注:1、支付方式参数不传会跳转到聚合收银台支付;

注:2、如果对接过程中出现异步参数名被转义成"¬ify url"这样会导致接口报错,请自行百度解决;

注:3、APP对接的话微信支付需要在app内调用webview组件跳转支付链接,然后需要在webview中手动设置referer,如 (Map extraHeaders = new HashMap();extraHeaders.put("Referer", "https://api.payqixiang.cn")) 可直接吊起。支付宝不需要,直接webview组件跳转支付链接即可。

支付结果通知

通知机制:用户付款成功后,我们会向您在发起付款接口传入的notify_url网址发送通知。您的服务器只要返回内容:success,就表示回调已收到。如果返回内容不是success,我们会再尝试回调5次。

通知类型:服务器异步通知(notify_url)、页面跳转通知(return_url)

请求方式:GET

请求参数说明:

字段名变量名必填类型示例值描述
商户IDpid是Int1001
七相系统订单号trade_no是String20160806151343349021七相系统订单号
商户订单号out_trade_no是String20160806151343349商户系统内部的订单号
支付方式type是Stringalipay支付方式列表
商品名称name是StringVIP会员
商品金额money是String1.00格式统一为两位小数
支付状态trade_status是StringTRADE_SUCCESS只有TRADE_SUCCESS是成功
业务扩展参数param否String
签名字符串sign是String202cb962ac59075b964b07152d234b70签名算法点此查看
签名类型sign_type是StringMD5默认为MD5
异步通知处理示例(验签 + 金额校验)
<?php
// notify_url.php —— 支付结果异步通知处理示例
// 建议:先记录回调日志,便于排查问题
file_put_contents(__DIR__ . '/notify.log', date('Y-m-d H:i:s') . ' ' . http_build_query($_GET) . PHP_EOL, FILE_APPEND);

$key = '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i'; // 商户密钥

// 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
$sign  = $_GET['sign'];
$check = $_GET;
unset($check['sign'], $check['sign_type']);
$check = array_filter($check, function ($v) { return $v !== '' && $v !== null; });
ksort($check);
$str = urldecode(http_build_query($check));
if (md5($str . $key) !== $sign) {
    exit('fail'); // 验签失败,可能是伪造通知,拒绝处理
}

// 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
//    $order = 查询本地订单($_GET['out_trade_no']);
//    if (number_format(floatval($_GET['money']), 2, '.', '') !== number_format(floatval($order['money']), 2, '.', '')) exit('fail');

// 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
//    ...... 你的业务逻辑(发货、开通会员等)

// 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
echo 'success';
// Spring Boot 示例,需引入 Hutool:cn.hutool:hutool-all
import cn.hutool.crypto.digest.DigestUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.TreeMap;

@RestController
public class NotifyController {

    /** 支付结果异步通知处理(验签 + 金额校验) */
    @RequestMapping("/notify_url.php")
    public String notify(HttpServletRequest request) {
        String key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"; // 商户密钥

        // 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
        // TreeMap 自动按参数名 ASCII 码从小到大排序
        TreeMap<String, String> params = new TreeMap<>();
        for (Map.Entry<String, String[]> e : request.getParameterMap().entrySet()) {
            String v = e.getValue()[0];
            if (!"sign".equals(e.getKey()) && !"sign_type".equals(e.getKey())
                    && v != null && !v.isEmpty()) {
                params.put(e.getKey(), v);
            }
        }
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> e : params.entrySet()) {
            if (sb.length() > 0) sb.append('&');
            sb.append(e.getKey()).append('=').append(e.getValue());
        }
        if (!DigestUtil.md5Hex(sb.toString() + key).equals(request.getParameter("sign"))) {
            return "fail"; // 验签失败,可能是伪造通知,拒绝处理
        }

        // 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
        // Order order = orderService.getByOutTradeNo(request.getParameter("out_trade_no"));
        // if (new java.math.BigDecimal(request.getParameter("money"))
        //         .compareTo(new java.math.BigDecimal(order.getMoney())) != 0) return "fail";

        // 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
        // ...... 你的业务逻辑(发货、开通会员等)

        // 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
        return "success";
    }
}
# -*- coding: utf-8 -*-
# Flask 示例:pip install flask
import hashlib
from flask import Flask, request

app = Flask(__name__)
KEY = '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i'  # 商户密钥


@app.route('/notify_url.php')
def notify():
    # 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
    sign = request.args.get('sign', '')
    check = {k: v for k, v in request.args.items()
             if k not in ('sign', 'sign_type') and v not in ('', None)}
    query = '&'.join(f'{k}={check[k]}' for k in sorted(check))
    if hashlib.md5((query + KEY).encode('utf-8')).hexdigest() != sign:
        return 'fail'  # 验签失败,可能是伪造通知,拒绝处理

    # 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
    # order = Order.query.filter_by(out_trade_no=request.args.get('out_trade_no')).first()
    # if f"{float(request.args.get('money')):.2f}" != f"{float(order.money):.2f}":
    #     return 'fail'

    # 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
    # ...... 你的业务逻辑(发货、开通会员等)

    # 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
    return 'success'


if __name__ == '__main__':
    app.run(port=80)
// Express 示例:npm install express
const crypto = require('crypto');
const express = require('express');
const app = express();
const KEY = '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i'; // 商户密钥

// 支付结果异步通知处理(验签 + 金额校验)
app.get('/notify_url.php', (req, res) => {
    // 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
    const sign = req.query.sign;
    const check = {};
    for (const k of Object.keys(req.query)) {
        if (k === 'sign' || k === 'sign_type') continue;
        if (req.query[k] === '' || req.query[k] === undefined) continue;
        check[k] = req.query[k];
    }
    const query = Object.keys(check).sort()
        .map(k => `${k}=${check[k]}`).join('&');
    const mySign = crypto.createHash('md5').update(query + KEY).digest('hex');
    if (mySign !== sign) {
        return res.send('fail'); // 验签失败,可能是伪造通知,拒绝处理
    }

    // 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
    // const order = await db.getOrder(req.query.out_trade_no);
    // if (Number(req.query.money).toFixed(2) !== Number(order.money).toFixed(2)) return res.send('fail');

    // 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
    // ...... 你的业务逻辑(发货、开通会员等)

    // 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
    res.send('success');
});

app.listen(80);
// Go 标准库示例(net/http):notify_url 处理器
package main

import (
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "net/http"
    "sort"
    "strings"
)

// 支付结果异步通知处理示例(验签 + 金额校验)
func notify(w http.ResponseWriter, r *http.Request) {
    key := "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i" // 商户密钥
    r.ParseForm()
    data := map[string]string{}
    for k, v := range r.Form {
        if len(v) > 0 {
            data[k] = v[0]
        }
    }

    // 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
    sign := data["sign"]
    keys := make([]string, 0, len(data))
    for k, v := range data {
        if v == "" || k == "sign" || k == "sign_type" {
            continue
        }
        keys = append(keys, k)
    }
    sort.Strings(keys)
    pairs := make([]string, 0, len(keys))
    for _, k := range keys {
        pairs = append(pairs, k+"="+data[k])
    }
    sum := md5.Sum([]byte(strings.Join(pairs, "&") + key))
    if hex.EncodeToString(sum[:]) != sign {
        fmt.Fprint(w, "fail") // 验签失败,可能是伪造通知,拒绝处理
        return
    }

    // 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
    // order := queryLocalOrder(data["out_trade_no"])
    // if data["money"] != fmt.Sprintf("%.2f", order.Money) {
    //     fmt.Fprint(w, "fail"); return
    // }

    // 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
    // ...... 你的业务逻辑(发货、开通会员等)

    // 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
    fmt.Fprint(w, "success")
}
// ASP.NET Core 示例(Controller)
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using System.Text;

[ApiController]
public class NotifyController : ControllerBase
{
    // 支付结果异步通知处理(验签 + 金额校验)
    [HttpGet("/notify_url.php")]
    public IActionResult Notify()
    {
        string key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"; // 商户密钥

        // 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
        var data = Request.Query.ToDictionary(x => x.Key, x => x.Value.ToString());
        string sign = data["sign"];
        var pairs = data.Where(p => p.Key != "sign" && p.Key != "sign_type" && !string.IsNullOrEmpty(p.Value))
            .OrderBy(p => p.Key, StringComparer.Ordinal)
            .Select(p => $"{p.Key}={p.Value}");
        string md5 = Convert.ToHexString(
            MD5.HashData(Encoding.UTF8.GetBytes(string.Join("&", pairs) + key))).ToLower();
        if (md5 != sign)
        {
            return Content("fail"); // 验签失败,可能是伪造通知,拒绝处理
        }

        // 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
        // var order = db.GetOrder(data["out_trade_no"]);
        // if (decimal.Parse(data["money"]).ToString("0.00") != decimal.Parse(order.Money).ToString("0.00"))
        //     return Content("fail");

        // 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
        // ...... 你的业务逻辑(发货、开通会员等)

        // 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
        return Content("success");
    }
}
// 说明:异步通知(notify_url)必须是公网可访问的服务端地址,App 客户端不直接接收通知。
// App 内常用做法:用户回到支付结果页后,轮询「查询单个订单」接口确认支付状态。
// 以下为 Kotlin(服务端 Ktor / Spring 通用)的验签处理逻辑:
import java.security.MessageDigest

fun handleNotify(data: Map<String, String>): String {
    val key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i" // 商户密钥

    // 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
    val query = data.filterKeys { it != "sign" && it != "sign_type" }
        .filterValues { it.isNotEmpty() }
        .toSortedMap() // 参数按 ASCII 升序
        .entries.joinToString("&") { "${it.key}=${it.value}" }
    val mySign = MessageDigest.getInstance("MD5").digest((query + key).toByteArray())
        .joinToString("") { "%02x".format(it) }
    if (mySign != data["sign"]) {
        return "fail" // 验签失败,可能是伪造通知,拒绝处理
    }

    // 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
    // val order = db.getOrderByOutTradeNo(data["out_trade_no"])
    // if (data["money"] != String.format("%.2f", order.money)) return "fail"

    // 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
    // ...... 你的业务逻辑(发货、开通会员等)

    // 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
    return "success"
}
// 说明:异步通知(notify_url)必须是公网可访问的服务端地址,App 客户端不直接接收通知。
// App 内常用做法:用户回到支付结果页后,轮询「查询单个订单」接口确认支付状态。
// 以下为 Swift(服务端 Vapor 通用)的验签处理逻辑:
import Foundation
import CryptoKit

func handleNotify(_ data: [String: String]) -> String {
    let key = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i" // 商户密钥

    // 1、验证签名:必须使用回调收到的参数参与验签(不要使用本地存储的值)
    let query = data.filter { $0.key != "sign" && $0.key != "sign_type" && !$0.value.isEmpty }
        .sorted { $0.key < $1.key } // 参数按 ASCII 升序
        .map { "\($0.key)=\($0.value)" }
        .joined(separator: "&")
    let mySign = Insecure.MD5.hash(data: Data((query + key).utf8))
        .map { String(format: "%02x", $0) }.joined()
    if mySign != data["sign"] {
        return "fail" // 验签失败,可能是伪造通知,拒绝处理
    }

    // 2、校验金额:回调金额格式统一为两位小数(如 1.00),需与商户本地订单金额比对
    // let order = try db.getOrder(outTradeNo: data["out_trade_no"] ?? "")
    // if data["money"] != String(format: "%.2f", order.money) { return "fail" }

    // 3、处理业务:更新本地订单为已支付(务必做幂等处理,防止重复回调重复入账)
    // ...... 你的业务逻辑(发货、开通会员等)

    // 4、返回 success 表示回调处理成功,否则平台会间隔重试 5 次
    return "success"
}

1、商户系统对于支付结果通知,一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现"假通知",造成资金损失;

2、请使用回调收到的参数参与验签(金额、订单号等均以回调参数为准),不要使用本地存储的值;

3、注意支付状态的参数返回来的如果是大写就要是大写的(TRADE_SUCCESS),不要转成小写;

4、验签时请使用回调收到的全部非空参数参与计算(除 sign、sign_type 外),name 只要收到且非空就必须参与签名,不要自行剔除某个字段;

5、部分境外服务器以及加了cdn或者防御的可能被屏蔽导致回调通知失败,请自行检查原因,建议用大厂服务器比如腾讯云阿里云等也有香港或境外服务器比较稳定,也可以直接通过调用查单接口来达到回调的目的;

6、商户系统不能仅依赖回调通知获取结果,尤其业务使用的服务器在境外的商户,需结合主动查询订单接口使用,避免遗漏或延迟问题,查询订单接口。

回调安全警示

提醒:验签通过不代表订单真的支付成功,回调只能当提醒,不能当支付凭证。

正确做法:

1、收到回调先验签;

2、回调参数白名单:回调只接受平台标准参数,标准字段为 pid、trade_no、out_trade_no、type、name、money、trade_status、sign、sign_type(param 可选),具体分三步校验:

① 字段名单校验:在验签之前,先遍历回调收到的所有参数,凡是不在标准字段列表里的,一律视为可疑回调,直接拒绝、不入账、不返回 success;

② 重复字段校验:每个标准字段只允许出现一次。攻击者常把 trade_status=TRADE_SUCCESS 等参数夹带在其它参数值里,使其与真实参数重复出现,遇到重复字段同样直接拒绝;

③ 最后再验签:确认参数集合合法后,再按MD5签名算法计算签名比对,验签失败直接拒绝。

3、入账前调用查询单个订单,返回 status=1 才入账;

4、金额必须与下单一致,同一订单号只入账一次。

MD5签名算法

1、将发送或接收到的所有参数按照参数名ASCII码从小到大排序(a-z),sign、sign_type、和空值不参与签名!

2、将排序后的参数拼接成URL键值对的格式,例如 a=b&c=d&e=f,参数值不要进行url编码;

3、再将拼接好的字符串与商户密钥KEY进行MD5加密得出sign签名参数,sign = md5 ( a=b&c=d&e=f + KEY )(注意:+ 为各语言的拼接符,不是字符!),md5结果为小写;

4、具体详细的签名教程点此查看。

MD5签名生成函数示例
<?php
/**
 * 生成MD5签名
 * @param  array  $data 参与签名的所有参数
 * @param  string $key  商户密钥
 * @return string 签名结果(32位小写)
 */
function getSign($data, $key)
{
    // 1、去除 sign、sign_type 以及空值参数(均不参与签名)
    unset($data['sign'], $data['sign_type']);
    $data = array_filter($data, function ($v) { return $v !== '' && $v !== null; });

    // 2、按参数名 ASCII 码从小到大排序(a-z)
    ksort($data);

    // 3、拼接成 URL 键值对格式:a=b&c=d&e=f(参数值不进行url编码)
    $str = urldecode(http_build_query($data));

    // 4、拼接商户密钥后进行 MD5 加密(结果为小写)
    return md5($str . $key);
}

// 使用示例:
$data = array('pid' => 1001, 'money' => '1.00', 'name' => 'VIP会员');
echo getSign($data, '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i');
// 输出:32位小写MD5字符串
// 需引入 Hutool 工具库,Maven 依赖:cn.hutool:hutool-all
import cn.hutool.crypto.digest.DigestUtil;

import java.util.Map;
import java.util.TreeMap;

public class SignUtil {

    /**
     * 生成MD5签名
     * @param data 参与签名的所有参数
     * @param key  商户密钥
     * @return 签名结果(32位小写)
     */
    public static String getSign(Map<String, String> data, String key) {
        // 1、去除 sign、sign_type 以及空值参数(均不参与签名)
        data.remove("sign");
        data.remove("sign_type");
        data.values().removeIf(v -> v == null || v.isEmpty());

        // 2、按参数名 ASCII 码从小到大排序(a-z)
        TreeMap<String, String> sorted = new TreeMap<>(data);

        // 3、拼接成 URL 键值对格式:a=b&c=d&e=f(参数值不进行url编码)
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> e : sorted.entrySet()) {
            if (sb.length() > 0) sb.append('&');
            sb.append(e.getKey()).append('=').append(e.getValue());
        }

        // 4、拼接商户密钥后进行 MD5 加密(结果为小写)
        return DigestUtil.md5Hex(sb.toString() + key);
    }
}
# -*- coding: utf-8 -*-
import hashlib


def get_sign(data: dict, key: str) -> str:
    """生成MD5签名

    :param data: 参与签名的所有参数
    :param key:  商户密钥
    :return:     签名结果(32位小写)
    """
    # 1、去除 sign、sign_type 以及空值参数(均不参与签名)
    data = {k: v for k, v in data.items()
            if k not in ('sign', 'sign_type') and v not in ('', None)}

    # 2、按参数名 ASCII 码从小到大排序(a-z),拼接成 a=b&c=d&e=f
    query = '&'.join(f'{k}={data[k]}' for k in sorted(data))

    # 3、拼接商户密钥后进行 MD5 加密(结果为小写)
    return hashlib.md5((query + key).encode('utf-8')).hexdigest()


# 使用示例:
data = {'pid': 1001, 'money': '1.00', 'name': 'VIP会员'}
print(get_sign(data, '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i'))
# 输出:32位小写MD5字符串
const crypto = require('crypto');

/**
 * 生成MD5签名
 * @param {Object} data 参与签名的所有参数
 * @param {string} key  商户密钥
 * @returns {string} 签名结果(32位小写)
 */
function getSign(data, key) {
    // 1、去除 sign、sign_type 以及空值参数(均不参与签名)
    const entries = Object.entries(data).filter(
        ([k, v]) => k !== 'sign' && k !== 'sign_type' && v !== '' && v !== undefined && v !== null
    );

    // 2、按参数名 ASCII 码从小到大排序(a-z),拼接成 a=b&c=d&e=f
    const query = entries.sort((a, b) => a[0].localeCompare(b[0]))
        .map(([k, v]) => `${k}=${v}`).join('&');

    // 3、拼接商户密钥后进行 MD5 加密(结果为小写)
    return crypto.createHash('md5').update(query + key).digest('hex');
}

// 使用示例:
const data = { pid: 1001, money: '1.00', name: 'VIP会员' };
console.log(getSign(data, '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i'));
// 输出:32位小写MD5字符串
// Go 标准库示例,无需第三方依赖
import (
    "crypto/md5"
    "encoding/hex"
    "sort"
    "strings"
)

// 生成MD5签名(结果为32位小写)
// data: 参与签名的所有参数;key: 商户密钥
func getSign(data map[string]string, key string) string {
    // 1、去除 sign、sign_type 以及空值参数(均不参与签名)
    keys := make([]string, 0, len(data))
    for k, v := range data {
        if v == "" || k == "sign" || k == "sign_type" {
            continue
        }
        keys = append(keys, k)
    }

    // 2、按参数名 ASCII 码从小到大排序(a-z)
    sort.Strings(keys)

    // 3、拼接成 URL 键值对格式:a=b&c=d&e=f(参数值不进行url编码)
    pairs := make([]string, 0, len(keys))
    for _, k := range keys {
        pairs = append(pairs, k+"="+data[k])
    }

    // 4、拼接商户密钥后进行 MD5 加密(结果为小写)
    sum := md5.Sum([]byte(strings.Join(pairs, "&") + key))
    return hex.EncodeToString(sum[:])
}

// 使用示例:
// data := map[string]string{"pid": "1001", "money": "1.00", "name": "VIP会员"}
// fmt.Println(getSign(data, "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"))
// 输出:32位小写MD5字符串
// .NET 6+ 示例
using System.Security.Cryptography;
using System.Text;

public class SignUtil
{
    /// <summary>
    /// 生成MD5签名(结果为32位小写)
    /// </summary>
    /// <param name="data">参与签名的所有参数</param>
    /// <param name="key">商户密钥</param>
    public static string GetSign(Dictionary<string, string> data, string key)
    {
        // 1、去除 sign、sign_type 以及空值参数(均不参与签名)
        var filtered = data.Where(p => p.Key != "sign" && p.Key != "sign_type" && !string.IsNullOrEmpty(p.Value));

        // 2、按参数名 ASCII 码从小到大排序(a-z),拼接成 a=b&c=d&e=f
        var query = string.Join("&", filtered
            .OrderBy(p => p.Key, StringComparer.Ordinal)
            .Select(p => $"{p.Key}={p.Value}"));

        // 3、拼接商户密钥后进行 MD5 加密(结果为小写)
        return Convert.ToHexString(
            MD5.HashData(Encoding.UTF8.GetBytes(query + key))).ToLower();
    }
}

// 使用示例:
// var data = new Dictionary<string, string> { ["pid"] = "1001", ["money"] = "1.00", ["name"] = "VIP会员" };
// Console.WriteLine(SignUtil.GetSign(data, "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"));
// 输出:32位小写MD5字符串
// Kotlin 示例(安卓 / 服务端通用)
import java.security.MessageDigest

/**
 * 生成MD5签名(结果为32位小写)
 * @param data 参与签名的所有参数
 * @param key  商户密钥
 */
fun getSign(data: Map<String, String>, key: String): String {
    // 1、去除 sign、sign_type 以及空值参数(均不参与签名)
    val filtered = data.filterKeys { it != "sign" && it != "sign_type" }
        .filterValues { it.isNotEmpty() }

    // 2、按参数名 ASCII 码从小到大排序(a-z),拼接成 a=b&c=d&e=f
    val query = filtered.toSortedMap()
        .entries.joinToString("&") { "${it.key}=${it.value}" }

    // 3、拼接商户密钥后进行 MD5 加密(结果为小写)
    return MessageDigest.getInstance("MD5").digest((query + key).toByteArray())
        .joinToString("") { "%02x".format(it) }
}

// 使用示例:
// val data = mapOf("pid" to "1001", "money" to "1.00", "name" to "VIP会员")
// println(getSign(data, "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"))
// 输出:32位小写MD5字符串
// iOS 示例(Swift 5+),使用系统 CryptoKit,无需第三方库
import Foundation
import CryptoKit

/// 生成MD5签名(结果为32位小写)
/// - Parameters:
///   - data: 参与签名的所有参数
///   - key: 商户密钥
func getSign(_ data: [String: String], key: String) -> String {
    // 1、去除 sign、sign_type 以及空值参数(均不参与签名)
    let filtered = data.filter { $0.key != "sign" && $0.key != "sign_type" && !$0.value.isEmpty }

    // 2、按参数名 ASCII 码从小到大排序(a-z),拼接成 a=b&c=d&e=f
    let query = filtered.sorted { $0.key < $1.key }
        .map { "\($0.key)=\($0.value)" }
        .joined(separator: "&")

    // 3、拼接商户密钥后进行 MD5 加密(结果为小写)
    let digest = Insecure.MD5.hash(data: Data((query + key).utf8))
    return digest.map { String(format: "%02x", $0) }.joined()
}

// 使用示例:
// let data = ["pid": "1001", "money": "1.00", "name": "VIP会员"]
// print(getSign(data, key: "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"))
// 输出:32位小写MD5字符串

支付方式列表

调用值描述
alipay支付宝
wxpay微信支付

设备类型列表

调用值描述
pc二维码链接-返回的是二维码链接(自行转换成二维码),默认不是微信原生二维码链接,若需原生链接请联系客服
mobileH5调起支付/APP支付-返回的是跳转URL(中间页跳转模式/仅支持手机端访问)
wechat微信内支付-返回的是跳转URL(JSAPI公众号支付/仅支持手机微信内支付)
jump仅返回支付跳转url(自适应页面,推荐)

提示1:若微信的H5调起支付不想用中间页模式的请换"jump"自适应的方法可直接跳转唤起;

提示2:如需开启微信内支付完成同步跳转你的页面功能,既"点金计划",请联系客服开通;

提示3:微信内支付建议直接跳转支付链接付款即可,不要转成二维码长按识别付款,容易风控;

提示4:pc返回的二维码链接一般默认不是微信原生二维码链接及支付页面,若需原生链接页面请联系客服。


[API]查询商户信息

URL地址:https://api.payqixiang.cn/api.php?act=query&pid={商户ID}&key={商户密钥}

请求方式:GET

请求参数说明:

字段名变量名必填类型示例值描述
操作类型act是Stringquery此API固定值
商户IDpid是Int1001
商户密钥key是String89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i

返回结果:

字段名变量名类型示例值描述
返回状态码codeInt11为成功,其它值为失败
商户IDpidInt1001商户ID
商户密钥keyString(32)89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i商户密钥
商户状态activeInt11为正常,0为封禁
商户手续费余额moneyString0.00商户所拥有的手续费余额
用不到忽略即可typeInt用不到忽略即可用不到忽略即可
用不到忽略即可accountString用不到忽略即可用不到忽略即可
用不到忽略即可usernameString用不到忽略即可用不到忽略即可
订单总数ordersInt30订单总数统计
今日订单order_todayInt15今日订单数量
昨日订单order_lastdayInt15昨日订单数量
查询商户信息示例
<?php
// 查询商户信息(GET请求)
$url = 'https://api.payqixiang.cn/api.php?act=query&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i';
$res = json_decode(file_get_contents($url), true);
if (isset($res['code']) && $res['code'] == 1) {
    echo '商户状态:' . ($res['active'] == 1 ? '正常' : '封禁');
    echo ',订单总数:' . $res['orders'] . ',今日订单:' . $res['order_today'];
} else {
    echo '查询失败:' . $res['msg'];
}
// 需引入 Hutool 工具库,Maven 依赖:cn.hutool:hutool-all
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class QueryDemo {
    public static void main(String[] args) {
        // 查询商户信息(GET请求)
        String url = "https://api.payqixiang.cn/api.php?act=query&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i";
        JSONObject res = JSONUtil.parseObj(HttpUtil.get(url));
        if (res.getInt("code") == 1) {
            System.out.println("商户状态:" + (res.getInt("active") == 1 ? "正常" : "封禁"));
            System.out.println("订单总数:" + res.getInt("orders") + ",今日订单:" + res.getInt("order_today"));
        } else {
            System.out.println("查询失败:" + res.getStr("msg"));
        }
    }
}
# pip install requests
import requests

# 查询商户信息(GET请求)
url = 'https://api.payqixiang.cn/api.php'
params = {
    'act': 'query',
    'pid': '1001',
    'key': '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i',
}
res = requests.get(url, params=params).json()
if res.get('code') == 1:
    print('商户状态:', '正常' if res['active'] == 1 else '封禁')
    print('订单总数:', res['orders'], ',今日订单:', res['order_today'])
else:
    print('查询失败:', res.get('msg'))
// Node.js 18+ 内置 fetch,无需额外依赖
const url = 'https://api.payqixiang.cn/api.php' +
    '?act=query&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i';

// 查询商户信息(GET请求)
const res = await fetch(url).then(r => r.json());
if (res.code === 1) {
    console.log('商户状态:', res.active === 1 ? '正常' : '封禁');
    console.log('订单总数:', res.orders, ',今日订单:', res.order_today);
} else {
    console.log('查询失败:', res.msg);
}
// Go 标准库示例,无需第三方依赖
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    // 查询商户信息(GET请求)
    url := "https://api.payqixiang.cn/api.php?act=query&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"
    resp, _ := http.Get(url)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)

    var res map[string]interface{}
    json.Unmarshal(body, &res)
    if res["code"] == float64(1) {
        status := "封禁"
        if res["active"] == float64(1) {
            status = "正常"
        }
        fmt.Println("商户状态:", status, ",订单总数:", res["orders"], ",今日订单:", res["order_today"])
    } else {
        fmt.Println("查询失败:", res["msg"])
    }
}
// .NET 6+ 示例,使用 HttpClient
using System.Text.Json;

// 查询商户信息(GET请求)
using var client = new HttpClient();
var url = "https://api.payqixiang.cn/api.php?act=query&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i";
using var doc = JsonDocument.Parse(await client.GetStringAsync(url));
var res = doc.RootElement;
if (res.GetProperty("code").GetInt32() == 1)
{
    var status = res.GetProperty("active").GetInt32() == 1 ? "正常" : "封禁";
    Console.WriteLine("商户状态:" + status);
    Console.WriteLine("订单总数:" + res.GetProperty("orders").GetInt32()
        + ",今日订单:" + res.GetProperty("order_today").GetInt32());
}
else
{
    Console.WriteLine("查询失败:" + (res.TryGetProperty("msg", out var msg) ? msg.GetString() : "未知错误"));
}
// 安卓示例,需引入 OkHttp:implementation("com.squareup.okhttp3:okhttp:4.12.0")
// org.json 已内置于 Android 系统,无需额外引入
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject

fun queryMerchantInfo() {
    // 查询商户信息(GET请求)
    val url = "https://api.payqixiang.cn/api.php?act=query&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"
    val request = Request.Builder().url(url).build()
    val body = OkHttpClient().newCall(request).execute().body?.string()

    val res = JSONObject(body)
    if (res.optInt("code") == 1) {
        val status = if (res.optInt("active") == 1) "正常" else "封禁"
        println("商户状态:$status,订单总数:${res.optInt("orders")},今日订单:${res.optInt("order_today")}")
    } else {
        println("查询失败:" + res.optString("msg"))
    }
}
// iOS 示例(Swift 5+),使用 URLSession,无需第三方库
import Foundation

func queryMerchantInfo() {
    // 查询商户信息(GET请求)
    let url = "https://api.payqixiang.cn/api.php?act=query&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"
    let request = URLRequest(url: URL(string: url)!)
    URLSession.shared.dataTask(with: request) { data, _, _ in
        guard let data = data,
              let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
              let code = json["code"] as? Int else { return }
        if code == 1 {
            let active = (json["active"] as? Int) == 1 ? "正常" : "封禁"
            print("商户状态:\(active),订单总数:\(json["orders"] ?? 0),今日订单:\(json["order_today"] ?? 0)")
        } else {
            print("查询失败:\(json["msg"] ?? "")")
        }
    }.resume()
}

[API]查询单个订单

URL地址:https://api.payqixiang.cn/api.php?act=order&pid={商户ID}&key={商户密钥}&out_trade_no={商户订单号}

请求方式:GET

请求参数说明:

字段名变量名必填类型示例值描述
操作类型act是Stringorder此API固定值
商户IDpid是Int1001
商户密钥key是String89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i
系统订单号trade_no选择String20160806151343312
商户订单号out_trade_no选择String20160806151343349

提示:系统订单号 和 商户订单号 二选一传入即可,如果都传入以系统订单号为准!

返回结果:

字段名变量名类型示例值描述
返回状态码codeInt11为成功,其它值为失败
返回信息msgString查询订单号成功!
七相支付订单号trade_noString2016080622555342651七相支付订单号
商户订单号out_trade_noString20160806151343349商户系统内部的订单号
第三方订单号api_trade_noString20160806151343349支付宝微信等接口方订单号
支付方式typeStringalipay支付方式列表
商户IDpidInt1001发起支付的商户ID
创建订单时间addtimeString2016-08-06 22:55:52
完成交易时间endtimeString2016-08-06 22:55:52
商品名称nameStringVIP会员
商品金额moneyString1.00
支付状态statusInt01为支付成功,0为未支付
业务扩展参数paramString默认留空
支付者账号(OpenID)buyerString默认留空
查询单个订单示例
<?php
// 查询单个订单(GET请求,trade_no 与 out_trade_no 二选一传入)
$url = 'https://api.payqixiang.cn/api.php?act=order&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&out_trade_no=20260929123456789';
$res = json_decode(file_get_contents($url), true);
if (isset($res['code']) && $res['code'] == 1) {
    echo '订单状态:' . ($res['status'] == 1 ? '已支付' : '未支付');
    echo ',订单金额:' . $res['money'];
} else {
    echo '查询失败:' . $res['msg'];
}
// 需引入 Hutool 工具库,Maven 依赖:cn.hutool:hutool-all
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class OrderQueryDemo {
    public static void main(String[] args) {
        // 查询单个订单(trade_no 与 out_trade_no 二选一传入)
        String url = "https://api.payqixiang.cn/api.php?act=order"
                + "&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"
                + "&out_trade_no=20260929123456789";
        JSONObject res = JSONUtil.parseObj(HttpUtil.get(url));
        if (res.getInt("code") == 1) {
            System.out.println("订单状态:" + (res.getInt("status") == 1 ? "已支付" : "未支付"));
            System.out.println("订单金额:" + res.getStr("money"));
        } else {
            System.out.println("查询失败:" + res.getStr("msg"));
        }
    }
}
# pip install requests
import requests

# 查询单个订单(trade_no 与 out_trade_no 二选一传入)
url = 'https://api.payqixiang.cn/api.php'
params = {
    'act': 'order',
    'pid': '1001',
    'key': '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i',
    'out_trade_no': '20260929123456789',
}
res = requests.get(url, params=params).json()
if res.get('code') == 1:
    print('订单状态:', '已支付' if res['status'] == 1 else '未支付')
    print('订单金额:', res['money'])
else:
    print('查询失败:', res.get('msg'))
// Node.js 18+ 内置 fetch,无需额外依赖
const url = 'https://api.payqixiang.cn/api.php' +
    '?act=order&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i' +
    '&out_trade_no=20260929123456789';

// 查询单个订单(trade_no 与 out_trade_no 二选一传入)
const res = await fetch(url).then(r => r.json());
if (res.code === 1) {
    console.log('订单状态:', res.status === 1 ? '已支付' : '未支付');
    console.log('订单金额:', res.money);
} else {
    console.log('查询失败:', res.msg);
}
// Go 标准库示例,无需第三方依赖
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    // 查询单个订单(GET请求,trade_no 与 out_trade_no 二选一传入)
    url := "https://api.payqixiang.cn/api.php?act=order&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&out_trade_no=20260929123456789"
    resp, _ := http.Get(url)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)

    var res map[string]interface{}
    json.Unmarshal(body, &res)
    if res["code"] == float64(1) {
        status := "未支付"
        if res["status"] == float64(1) {
            status = "已支付"
        }
        fmt.Println("订单状态:", status, ",订单金额:", res["money"])
    } else {
        fmt.Println("查询失败:", res["msg"])
    }
}
// .NET 6+ 示例,使用 HttpClient
using System.Text.Json;

// 查询单个订单(GET请求,trade_no 与 out_trade_no 二选一传入)
using var client = new HttpClient();
var url = "https://api.payqixiang.cn/api.php?act=order&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&out_trade_no=20260929123456789";
using var doc = JsonDocument.Parse(await client.GetStringAsync(url));
var res = doc.RootElement;
if (res.GetProperty("code").GetInt32() == 1)
{
    var status = res.GetProperty("status").GetInt32() == 1 ? "已支付" : "未支付";
    Console.WriteLine("订单状态:" + status + ",订单金额:" + res.GetProperty("money").GetString());
}
else
{
    Console.WriteLine("查询失败:" + (res.TryGetProperty("msg", out var msg) ? msg.GetString() : "未知错误"));
}
// 安卓示例,需引入 OkHttp:implementation("com.squareup.okhttp3:okhttp:4.12.0")
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject

fun queryOrder() {
    // 查询单个订单(GET请求,trade_no 与 out_trade_no 二选一传入)
    val url = "https://api.payqixiang.cn/api.php?act=order&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&out_trade_no=20260929123456789"
    val request = Request.Builder().url(url).build()
    val body = OkHttpClient().newCall(request).execute().body?.string()

    val res = JSONObject(body)
    if (res.optInt("code") == 1) {
        val status = if (res.optInt("status") == 1) "已支付" else "未支付"
        println("订单状态:$status,订单金额:${res.optString("money")}")
    } else {
        println("查询失败:" + res.optString("msg"))
    }
}
// iOS 示例(Swift 5+),使用 URLSession,无需第三方库
import Foundation

func queryOrder() {
    // 查询单个订单(GET请求,trade_no 与 out_trade_no 二选一传入)
    let url = "https://api.payqixiang.cn/api.php?act=order&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&out_trade_no=20260929123456789"
    let request = URLRequest(url: URL(string: url)!)
    URLSession.shared.dataTask(with: request) { data, _, _ in
        guard let data = data,
              let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
              let code = json["code"] as? Int else { return }
        if code == 1 {
            let status = (json["status"] as? Int) == 1 ? "已支付" : "未支付"
            print("订单状态:\(status),订单金额:\(json["money"] ?? "")")
        } else {
            print("查询失败:\(json["msg"] ?? "")")
        }
    }.resume()
}

[API]批量查询订单

URL地址:https://api.payqixiang.cn/api.php?act=orders&pid={商户ID}&key={商户密钥}

请求方式:GET

请求参数说明:

字段名变量名必填类型示例值描述
操作类型act是Stringorders此API固定值
商户IDpid是Int1001
商户密钥key是String89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i
查询订单数量limit否Int20返回的订单数量,最大50
页码page否Int1当前查询的页码

返回结果:

字段名变量名类型示例值描述
返回状态码codeInt11为成功,其它值为失败
返回信息msgString查询订单记录成功!
订单列表dataArray订单列表
批量查询订单示例
<?php
// 批量查询订单(GET请求)
$url = 'https://api.payqixiang.cn/api.php?act=orders&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&limit=20&page=1';
$res = json_decode(file_get_contents($url), true);
if (isset($res['code']) && $res['code'] == 1) {
    foreach ($res['data'] as $order) {
        echo $order['out_trade_no'] . ' - ' . $order['money'] . '元 - ' . ($order['status'] == 1 ? '已支付' : '未支付') . PHP_EOL;
    }
} else {
    echo '查询失败:' . $res['msg'];
}
// 需引入 Hutool 工具库,Maven 依赖:cn.hutool:hutool-all
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class OrdersQueryDemo {
    public static void main(String[] args) {
        // 批量查询订单(GET请求)
        String url = "https://api.payqixiang.cn/api.php?act=orders"
                + "&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&limit=20&page=1";
        JSONObject res = JSONUtil.parseObj(HttpUtil.get(url));
        if (res.getInt("code") == 1) {
            JSONArray list = res.getJSONArray("data");
            for (Object o : list) {
                JSONObject order = (JSONObject) o;
                System.out.println(order.getStr("out_trade_no") + " - "
                        + order.getStr("money") + "元 - "
                        + (order.getInt("status") == 1 ? "已支付" : "未支付"));
            }
        } else {
            System.out.println("查询失败:" + res.getStr("msg"));
        }
    }
}
# pip install requests
import requests

# 批量查询订单(GET请求)
url = 'https://api.payqixiang.cn/api.php'
params = {
    'act': 'orders',
    'pid': '1001',
    'key': '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i',
    'limit': 20,
    'page': 1,
}
res = requests.get(url, params=params).json()
if res.get('code') == 1:
    for order in res['data']:
        print(order['out_trade_no'], '-', order['money'], '元 -',
              '已支付' if order['status'] == 1 else '未支付')
else:
    print('查询失败:', res.get('msg'))
// Node.js 18+ 内置 fetch,无需额外依赖
const url = 'https://api.payqixiang.cn/api.php' +
    '?act=orders&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&limit=20&page=1';

// 批量查询订单(GET请求)
const res = await fetch(url).then(r => r.json());
if (res.code === 1) {
    for (const order of res.data) {
        console.log(`${order.out_trade_no} - ${order.money}元 - ${order.status === 1 ? '已支付' : '未支付'}`);
    }
} else {
    console.log('查询失败:', res.msg);
}
// Go 标准库示例,无需第三方依赖
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    // 批量查询订单(GET请求)
    url := "https://api.payqixiang.cn/api.php?act=orders&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&limit=20&page=1"
    resp, _ := http.Get(url)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)

    var res map[string]interface{}
    json.Unmarshal(body, &res)
    if res["code"] == float64(1) {
        if list, ok := res["data"].([]interface{}); ok {
            for _, item := range list {
                order := item.(map[string]interface{})
                status := "未支付"
                if order["status"] == float64(1) {
                    status = "已支付"
                }
                fmt.Println(order["out_trade_no"], "-", order["money"], "元 -", status)
            }
        }
    } else {
        fmt.Println("查询失败:", res["msg"])
    }
}
// .NET 6+ 示例,使用 HttpClient
using System.Text.Json;

// 批量查询订单(GET请求)
using var client = new HttpClient();
var url = "https://api.payqixiang.cn/api.php?act=orders&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&limit=20&page=1";
using var doc = JsonDocument.Parse(await client.GetStringAsync(url));
var res = doc.RootElement;
if (res.GetProperty("code").GetInt32() == 1)
{
    foreach (var order in res.GetProperty("data").EnumerateArray())
    {
        var status = order.GetProperty("status").GetInt32() == 1 ? "已支付" : "未支付";
        Console.WriteLine(order.GetProperty("out_trade_no").GetString() + " - "
            + order.GetProperty("money").GetString() + "元 - " + status);
    }
}
else
{
    Console.WriteLine("查询失败:" + (res.TryGetProperty("msg", out var msg) ? msg.GetString() : "未知错误"));
}
// 安卓示例,需引入 OkHttp:implementation("com.squareup.okhttp3:okhttp:4.12.0")
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject

fun queryOrders() {
    // 批量查询订单(GET请求)
    val url = "https://api.payqixiang.cn/api.php?act=orders&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&limit=20&page=1"
    val request = Request.Builder().url(url).build()
    val body = OkHttpClient().newCall(request).execute().body?.string()

    val res = JSONObject(body)
    if (res.optInt("code") == 1) {
        val orders = res.optJSONArray("data") ?: return
        for (i in 0 until orders.length()) {
            val order = orders.optJSONObject(i) ?: continue
            val status = if (order.optInt("status") == 1) "已支付" else "未支付"
            println("${order.optString("out_trade_no")} - ${order.optString("money")}元 - $status")
        }
    } else {
        println("查询失败:" + res.optString("msg"))
    }
}
// iOS 示例(Swift 5+),使用 URLSession,无需第三方库
import Foundation

func queryOrders() {
    // 批量查询订单(GET请求)
    let url = "https://api.payqixiang.cn/api.php?act=orders&pid=1001&key=89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i&limit=20&page=1"
    let request = URLRequest(url: URL(string: url)!)
    URLSession.shared.dataTask(with: request) { data, _, _ in
        guard let data = data,
              let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
              let code = json["code"] as? Int else { return }
        if code == 1, let orders = json["data"] as? [[String: Any]] {
            for order in orders {
                let status = (order["status"] as? Int) == 1 ? "已支付" : "未支付"
                print("\(order["out_trade_no"] ?? "") - \(order["money"] ?? "")元 - \(status)")
            }
        } else {
            print("查询失败:\(json["msg"] ?? "")")
        }
    }.resume()
}

[API]提交订单退款

注意:需要先在商户后台开启订单退款API接口开关,才能调用该接口发起订单退款。

URL地址:https://api.payqixiang.cn/api.php?act=refund

请求方式:POST

请求参数说明:

字段名变量名必填类型示例值描述
商户IDpid是Int1001
商户密钥key是String89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i
七相系统订单号trade_no特殊可选String20160806151343349021七相系统订单号
商户订单号out_trade_no特殊可选String20160806151343349订单支付时传入的商户订单号,商家自定义且保证商家系统中唯一
退款金额money是String1.50少数通道需要与原订单金额一致

注:trade_no、out_trade_no 不能同时为空,如果都传了以trade_no为准。

返回结果:

字段名变量名类型示例值描述
返回状态码codeInt11或0为成功,其它值为失败
返回信息msgString退款成功
提交订单退款示例
<?php
// 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
$api  = 'https://api.payqixiang.cn/api.php?act=refund';
$data = array(
    'pid'          => '1001',
    'key'          => '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i',
    'out_trade_no' => '20260929123456789', // 与 trade_no 二选一
    'money'        => '1.00',              // 退款金额
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

$res = json_decode($result, true);
if (isset($res['code']) && ($res['code'] == 1 || $res['code'] == 0)) {
    echo '退款成功';
} else {
    echo '退款失败:' . (isset($res['msg']) ? $res['msg'] : '未知错误');
}
// 需引入 Hutool 工具库,Maven 依赖:cn.hutool:hutool-all
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class RefundDemo {
    public static void main(String[] args) {
        // 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
        String api = "https://api.payqixiang.cn/api.php?act=refund";
        String result = HttpRequest.post(api)
                .form("pid", "1001")
                .form("key", "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i")
                .form("out_trade_no", "20260929123456789") // 与 trade_no 二选一
                .form("money", "1.00")                     // 退款金额
                .execute()
                .body();

        JSONObject res = JSONUtil.parseObj(result);
        int code = res.getInt("code");
        if (code == 1 || code == 0) { // 1或0均为成功
            System.out.println("退款成功");
        } else {
            System.out.println("退款失败:" + res.getStr("msg", "未知错误"));
        }
    }
}
# pip install requests
import requests

# 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
api = 'https://api.payqixiang.cn/api.php?act=refund'
data = {
    'pid': '1001',
    'key': '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i',
    'out_trade_no': '20260929123456789',  # 与 trade_no 二选一
    'money': '1.00',                      # 退款金额
}
res = requests.post(api, data=data).json()

if res.get('code') in (0, 1):  # 1或0均为成功
    print('退款成功')
else:
    print('退款失败:', res.get('msg', '未知错误'))
// Node.js 18+ 内置 fetch,无需额外依赖
// 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
const api = 'https://api.payqixiang.cn/api.php?act=refund';
const body = new URLSearchParams({
    pid: '1001',
    key: '89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i',
    out_trade_no: '20260929123456789', // 与 trade_no 二选一
    money: '1.00',                     // 退款金额
});

const res = await fetch(api, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body,
}).then(r => r.json());

if (res.code === 1 || res.code === 0) { // 1或0均为成功
    console.log('退款成功');
} else {
    console.log('退款失败:', res.msg || '未知错误');
}
// Go 标准库示例,无需第三方依赖
package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
)

func main() {
    // 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
    api := "https://api.payqixiang.cn/api.php?act=refund"
    form := url.Values{
        "pid":          {"1001"},
        "key":          {"89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i"},
        "out_trade_no": {"20260929123456789"}, // 与 trade_no 二选一
        "money":        {"1.00"},              // 退款金额
    }
    resp, err := http.PostForm(api, form)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    fmt.Println(string(body)) // 解析 JSON:code 为 1 或 0 均为退款成功
}
// .NET 6+ 示例,使用 HttpClient
using System.Text.Json;

// 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
using var client = new HttpClient();
var api = "https://api.payqixiang.cn/api.php?act=refund";
var form = new Dictionary<string, string>
{
    ["pid"] = "1001",
    ["key"] = "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i",
    ["out_trade_no"] = "20260929123456789", // 与 trade_no 二选一
    ["money"] = "1.00",                     // 退款金额
};
var resp = await client.PostAsync(api, new FormUrlEncodedContent(form));
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var res = doc.RootElement;
int code = res.GetProperty("code").GetInt32();
if (code == 1 || code == 0) // 1或0均为成功
{
    Console.WriteLine("退款成功");
}
else
{
    Console.WriteLine("退款失败:" + (res.TryGetProperty("msg", out var msg) ? msg.GetString() : "未知错误"));
}
// 安卓示例,需引入 OkHttp:implementation("com.squareup.okhttp3:okhttp:4.12.0")
// 网络请求需在子线程执行(如协程 withContext(Dispatchers.IO))
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject

fun refundOrder() {
    // 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
    val api = "https://api.payqixiang.cn/api.php?act=refund"
    val form = FormBody.Builder()
        .add("pid", "1001")
        .add("key", "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i")
        .add("out_trade_no", "20260929123456789") // 与 trade_no 二选一
        .add("money", "1.00")                     // 退款金额
        .build()
    val request = Request.Builder().url(api).post(form).build()
    val body = OkHttpClient().newCall(request).execute().body?.string()

    val res = JSONObject(body)
    val code = res.optInt("code", -1)
    if (code == 1 || code == 0) { // 1或0均为成功
        println("退款成功")
    } else {
        println("退款失败:" + res.optString("msg", "未知错误"))
    }
}
// iOS 示例(Swift 5+),使用 URLSession,无需第三方库
import Foundation

func refundOrder() {
    // 提交订单退款(POST请求,需先在商户后台开启订单退款API接口开关)
    let api = "https://api.payqixiang.cn/api.php?act=refund"
    let form = [
        "pid": "1001",
        "key": "89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i",
        "out_trade_no": "20260929123456789", // 与 trade_no 二选一
        "money": "1.00",                     // 退款金额
    ]
    var request = URLRequest(url: URL(string: api)!)
    request.httpMethod = "POST"
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpBody = form.map { "\($0.key)=\($0.value)" }
        .joined(separator: "&").data(using: .utf8)

    URLSession.shared.dataTask(with: request) { data, _, _ in
        guard let data = data,
              let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
              let code = json["code"] as? Int else { return }
        if code == 1 || code == 0 { // 1或0均为成功
            print("退款成功")
        } else {
            print("退款失败:\(json["msg"] ?? "未知错误")")
        }
    }.resume()
}

注意:退款是从当天未结算的款项里面退的,退款是扣不了已经提现到你银行卡里面的款项。如果当天收款小于本次退款的金额,请在自己业务网站系统里自己下单支付一笔,再来提交本次退款。例如:当天只收了100块钱,但是要退200块钱,就需要自己去自己业务网站系统里自己下单支付一笔,只要大于等于退款的金额即可。

SDK下载

注意:注意查看DEMO里面的支付网关地址是否与开发文档上面的支付网关地址一致,若不一致请以开发文档上面地址为准!!!

你也可以把以上开发文档所有的文字复制到豆包AI或者其他AI上面,告诉AI你的要求,让AI帮你生成你对应语言的支付接口代码。