小程序实现微信支付开发

微信支付需要服务号、商户号和HTTPS域名,以下是具体说明:

一、服务号

  • 申请服务号:必须申请微信服务号,且需以企业身份申请,服务号认证费用为300元每年。申请地址为:https://mp.weixin.qq.com/cgi。

  • 开通权限:要实现服务号对接微信支付功能,需到微信公众平台>开发>接口权限页面,开通网页授权和微信支付权限。

二、商户号

  • 获取商户号:登录微信公众号或微信小程序后台,确认“微信支付”部分的状态是“已申请”。申请通过后,会收到一封来自微信支付的邮件,邮件中有微信支付商户号等信息。也可在微信支付商户后台(pay.weixin.qq.com)->【账户中心】->【账户设置-商户信息】查看微信支付商户号。

  • 配置密钥:到微信支付商户平台>账户中心>API安全页面的API密钥处设置密钥。

三、HTTPS域名

  • 域名要求:域名必须通过ICP备案,且填写格式不包含“HTTP://”或“HTTPS://”。同时,域名必须支持SSL/TLS,即必须启用HTTPS协议,确保域名在公网可正常访问,且服务器稳定。

  • 配置方法

    • 准备域名:若没有域名,可在域名注册服务商购买,并完成ICP备案。

    • 设置HTTPS:为域名配置HTTPS证书,可通过Let’s Encrypt免费证书或云服务商提供的免费证书服务获取,并将证书部署到服务器上。

    • 配置域名解析:登录域名服务商控制台,设置A记录,将域名指向服务器公网IP地址。

    • 微信支付后台配置:登录微信支付商户平台,根据具体支付类型(如H5支付等)的配置路径,设置相应的支付域名,配置后一般10分钟内生效。

四、小程序开发 

 开发之前要选择对应的支付方式,不同的方式对应不同场景。

  1. 安装依赖

    • 推荐使用uni-app官方提供的uni-pay插件,或者从uni-app插件市场选择其他可靠的支付插件。

    • 使用unified-payment插件,可在项目根目录中打开终端并输入以下命令进行安装:npm install unified-payment。安装完成后,需要在main.js文件中引入插件。

  2. 获取登录凭证(code)

在小程序端,调用wx.login()接口获取用户的登录凭证(code)。这个code是临时登录凭证,用于后续换取用户的openid。

wx.login({
    success: function(res) {
        if (res.code) {
            // 发送 res.code 到后台换取 openId, sessionKey, unionId
        }
    }
});

3、获取openid:将获取的code发送到服务器端,服务器端使用code向微信服务器请求,获取用户的openid。openid是用户的唯一标识,用于后续创建订单和支付。

4、创建订单

  • 在服务器端,根据业务需求创建订单,并生成订单号。订单信息通常包括商品ID、数量、价格等

5、获取支付参数

  • 服务器端调用微信支付API,使用openid、订单号等信息生成预支付订单,并获取支付参数。这些参数包括:

    • appId:公众账号ID。

    • timeStamp:时间戳。

    • nonceStr:随机字符串。

    • package:数据包,格式为prepay_id=预支付会话标识

    • signType:签名算法,目前支持MD5

    • paySign:签名。

  • 以下是一个服务器端获取微信支付参数的示例代码(使用Node.js + Koa):

const Koa = require('koa');
const Router = require('koa-router');
const request = require('request');
const crypto = require('crypto');
const app = new Koa();
const router = new Router();
router.post('/getWxPayParams', async (ctx) => {
    const { openid, total_fee } = ctx.request.body;
    const appid = '你的微信公众平台应用ID';
    const mch_id = '你的商户号';
    const nonce_str = Math.random().toString(36).substr(2, 15);
    const body = '商品描述';
    const out_trade_no = '订单号';
    const spbill_create_ip = '用户IP';
    const notify_url = '回调通知地址';
    const trade_type = 'JSAPI';
    const key = '你的API密钥';
    const sign = createSign({
        appid,
        mch_id,
        nonce_str,
        body,
        out_trade_no,
        total_fee,
        spbill_create_ip,
        notify_url,
        trade_type,
        openid,
    }, key);
    const formData = `<xml>
        <appid>${appid}</appid>
        <mch_id>${mch_id}</mch_id>
        <nonce_str>${nonce_str}</nonce_str>
        <sign>${sign}</sign>
        <body>${body}</body>
        <out_trade_no>${out_trade_no}</out_trade_no>
        <total_fee>${total_fee}</total_fee>
        <spbill_create_ip>${spbill_create_ip}</spbill_create_ip>
        <notify_url>${notify_url}</notify_url>
        <trade_type>${trade_type}</trade_type>
        <openid>${openid}</openid>
    </xml>`;
    const result = await new Promise((resolve, reject) => {
        request({
            url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
            method: 'POST',
            body: formData
        }, (error, response, body) => {
            if (!error && response.statusCode === 200) {
                resolve(body);
            } else {
                reject(error);
            }
        });
    });
    const parseString = require('xml2js').parseString;
    let res;
    parseString(result, (err, json) => {
        if (err) {
            throw err;
        }
        res = json.xml;
    });
    const timeStamp = Math.floor(Date.now() / 1000).toString();
    const nonceStr = res.nonce_str[0];
    const prepay_id = res.prepay_id[0];
    const paySign = createSign({
        appId: appid,
        timeStamp,
        nonceStr,
        package: `prepay_id=${prepay_id}`,
        signType: 'MD5'
    }, key);
    ctx.body = {
        appId: appid,
        timeStamp,
        nonceStr,
        package: `prepay_id=${prepay_id}`,
        signType: 'MD5',
        paySign,
    };
});
function createSign(params, key) {
    const string = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&') + `&key=${key}`;
    return crypto.createHash('md5').update(string).digest('hex').toUpperCase();
}
app.use(router.routes());
app.listen(3000);

6、前端调用支付接口

  • 在前端(uni-app项目),当用户点击支付按钮时,前端将向服务器发送请求,获取上述支付参数。然后,使用uni-pay插件或其他支付插件,调用微信支付API的wx.requestPayment()方法,传入支付参数,拉起支付密码框,完成支付。

uni.requestPayment({
    timeStamp: '时间戳',
    nonceStr: '随机字符串',
    package: 'prepay_id=预支付会话标识',
    signType: '签名算法',
    paySign: '签名',
    success: function (res) {
        console.log('支付成功', res);
    },
    fail: function (err) {
        console.error('支付失败', err);
    }
});

7、处理支付结果:根据支付成功或失败的回调函数中的逻辑进行处理,例如弹出提示框告知用户支付结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

研创通之逍遥峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值