沙箱环境 (Beta) 是协助开发者进行接口功能开发及主要功能联调的辅助环境,模拟了开放平台部分产品的主要功能和主要逻辑。可用于在产品上线前了解环境、组合和调试各种接口。
打开 支付宝开发者中心 并登录,点击 => 进入我的控制台(也可能登录之后自动进入),
在开发者中心中点击开发服务下的研发服务,就进入沙箱环境页面了,
在沙箱应用可以看到基本配置。
点击 RSA2(SHA256)密钥 设置,
点击 支付宝密钥生成器,下载对应版本的工具,下载完成后将工具安装在不包含空格的目录中,
然后点打开,点击生成密钥,即可生成商户应用私钥与商户应用公钥。然后点击复制公钥。
回到沙箱界面,选择公钥,并把刚刚复制的公钥粘贴进去;
然后就可以得到支付宝公钥了,代码中会用到。
首先安装 Alipay SDK:
npm install alipay-sdk -S
// sdk 配置语法
alipaySdk.exec(method, params, options);
由于每次调用 AlipaySdk 的 API 都是同一个对象,所以该对象只需要实例化一次:
// alipay.js 这里单独存放一个文件中,需要时引入即可
const AlipaySdk = require('alipay-sdk').default; // 引入 SDK
const alipaySdk = new AlipaySdk({
AppId: 'appId', // 开放平台上创建应用时生成的 appId
signType: 'RSA2', // 签名算法,默认 RSA2
gateway: 'https://openapi.alipaydev.com/gateway.do', // 支付宝网关地址 ,沙箱环境下使用时需要修改
alipayPublicKey: 'public_key', // 支付宝公钥,需要对结果验签时候必填
privateKey: 'private_key', // 应用私钥字符串
});module.exports = alipaySdk;
要完成支付,需要以下几个步骤,
先来看看服务端接口的实现:
var express = require('express');
var router = express.Router();const alipaySdk = require('../utils/alipay');
const AlipayFormData = require('alipay-sdk/lib/form').default; // alipay.trade.page.pay 返回的内容为 Form 表单
router.post('/pcpay', (req, res) => {
(async () => { // 调用 setMethod 并传入 get,会返回可以跳转到支付页面的 url
const formData = new AlipayFormData();
formData.setMethod('get');
// 通过 addField 增加参数
// 在用户支付完成之后,支付宝服务器会根据传入的 notify_url,以 POST 请求的形式将支付结果作为参数通知到商户系统。
formData.addField('notifyUrl', 'http://www.com/notify'); // 支付成功回调地址,必须为可以直接访问的地址,不能带参数
formData.addField('bizContent', {
outTradeNo: req.body.outTradeNo, // 商户订单号,64个字符以内、可包含字母、数字、下划线,且不能重复
productCode: 'FAST_INSTANT_TRADE_PAY', // 销售产品码,与支付宝签约的产品码名称,仅支持FAST_INSTANT_TRADE_PAY
totalAmount: '0.01', // 订单总金额,单位为元,精确到小数点后两位
subject: '商品', // 订单标题
body: '商品详情', // 订单描述
}); // 如果需要支付后跳转到商户界面,可以增加属性"returnUrl"
const result = await alipaySdk.exec(
'alipay.trade.page.pay', // 统一收单下单并支付页面接口
{}, // api 请求的参数(包含“公共请求参数”和“业务参数”)
{ formData: formData }, ); // result 为可以跳转到支付链接的 url
res.json({ url: result }); })();});
然后就是前端页面,这个比较简单,就是点击支付按钮,向服务器发起请求,拿到返回的支付页面地址后进行跳转:
$.ajax({
method: 'POST',
url: '/alipay/pcpay',
data: { outTradeNo // 商户订单号,必须保证唯一,生成方法有很多,可以去看我的代码 }}).done(function(res) {
window.open(res.url, '_blank');
}).fail(function(err) {
console.log(err);
});
如果上诉没有问题,我们应该能看到这样的页面:
如果是使用沙箱环境,必须下载沙箱钱包来完成支付,下载地方如下所示:
下载完成后,使用沙箱提供的账号登陆即可,随便充值,随便消费,其实沙箱钱包里就是一个数字而已。
然后这里补充一个点,就是前端如何判断用户是否已经支付。我们都知道前端的手段是不被信任的,所以不能依赖前端来判断,唯一可靠的方法是使用支付宝 API 中的 alipay.trade.query 来查询是否已经完成支付。
可以通过前端发送订单号到服务器进行查询,服务器向支付宝服务器查询该订单号支付的相关信息,通过交易状态来确定是否已经完成支付,具体服务器配置如下:
const axIOS = require('axios');
const alipaySdk = require('../utils/alipay');
const AlipayFormData = require('alipay-sdk/lib/form').default;
router.get('/query', function(req, res) {
(async function() {
const { outTradeNo } = req.query; const formData = new AlipayFormData(); formData.setMethod('get');
formData.addField('bizContent', {
outTradeNo }); // 通过该接口主动查询订单状态 const result = await alipaySdk.exec( 'alipay.trade.query',
{}, { formData: formData }, ); axios({ method: 'GET',
url: result }) .then(data => {
let r = data.data.alipay_trade_query_response; if(r.code === '10000') { // 接口调用成功
switch(r.trade_status) { case 'WAIT_BUYER_PAY':
res.send('交易创建,等待买家付款');
break;
case 'TRADE_CLOSED':
res.send('未付款交易超时关闭,或支付完成后全额退款');
break;
case 'TRADE_SUCCESS':
res.send('交易支付成功');
break;
case 'TRADE_FINISHED':
res.send('交易结束,不可退款');
break;
} } else if(r.code === '40004') {
res.send('交易不存在');
} }) .catch(err => { res.json({ msg: '查询失败',
err }); }); })();});
【本文转载自我的微信公众号-飞舟技术社区】
【喜欢我的文章欢迎 转发 点赞 与 关注,我会经常与大家分享前端的知识点的】