企业用户使用备案资源包进行网站备案ICP并开通微信H5支付(附API V3版本支付nodejs代码)

业务场景:

企业扩张业务,需开设网站拓宽业务范围,增加收入渠道。

例如:

  1. 某公司需要把自营的AI智能化服务在网络上经营。
  2. 某硬件设备公司自营的网络商店。

注意:若是进行交易平台或游戏等其他经营项目,还会需要其他资质文件,请查阅相关法律法规,在这里不进行赘述。

相关概念介绍:

什么是备案

根据国务院令第292号《互联网信息服务管理办法》和《非经营性互联网信息服务备案管理办法》规定,国家对经营性互联网信息服务实行许可制度,对非经营性互联网信息服务实行备案制度。未获取许可或者未履行备案手续的,不得从事互联网信息服务,否则属于违法行为。

因此,所有对中国大陆境内提供服务的网站都必须先进行 ICP 备案,备案成功并获取通信管理局下发的 ICP 备案号后才能开通访问。

微信H5支付

H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付。主要用于触屏版的手机浏览器请求微信支付的场景。可以方便的从外部浏览器唤起微信支付。

前期准备:

1. 以企业为主体,注册腾讯云账号;

2. 购买网络备案资源包(使用腾讯云备案本身是免费的,但需要购买对应的资源包)

可以选择的资源包类型:https://cloud.tencent.com/document/product/243/18793;

本文以购买的云函数资源包进行说明

3. 开通微信支付商户号;

详细步骤:

1. 网站备案

1.1 验证备案主体信息

首先登陆腾讯云账号,在控制台中搜索“网站备案”,进入《我的备案》页面:

如实填入主体信息

这个步骤需要填写的东西比较简单,按公司实际的状况填写即可,期间需要准备公司的营业执照以及负责人身份证的照片,填好以后腾讯云会先进行验证,时间大概是在7个工作日左右。

1.2 填写备案网站的信息

主体审核完成之后,可以进行下一步的操作:

点击“新增网站”

在《我的备案》页面,点击“新增网站”按钮,进入如下页面:

确认主体信息后会进入下方页面:

填写网站信息

填写已注册的域名信息:

如果尚未注册域名信息,请先前往控制台,搜索《域名注册》进行操作。

域名注册官方详解:https://cloud.tencent.com/document/product/242/9595

在云资源处,选择我们之前已购买的云函数serverless资源包。

注意:IP地址会自动填写,不用改动。

填写完毕之后点击“立即验证”会弹出如下所示对话框:

点击下一步

之后进入如下页面:

网站信息填写页面

本页面需要填写网站的名称,例如《淘宝网》《百度》,按需要填写即可。

备注信息也需要如实填写,例如:展示XX公司概况,以及生产销售的设备详情的网站,并可以在网络上进行订购其产品或者服务。

下方选择“复用责任人模板”就可以不用重复填写信息。

另外关于前置审批的说明:

前置审批类型-条件与限制

常见问题

  • 什么样的网站需要办理前置审批?
  • 答:您好,根据《互联网信息服务管理办法》第五条规定和原《信息产业部第33号令》规定,拟从事新闻、出版、药品和医疗器械、文化、广播电影电视节目、网络游戏等互联网信息服务,需要进行前置审批,才能通过备案。
  • 如何办理前置审批?
  • 答:前置审批资料的办理,需要各企事业单位主动找相关部门申请,个人无法办理前置审批文件。相关单位以及前置审批包含的有以下文件。

说明:如果您的备案涉及到前置审批的办理,请根据涉及的前置审批类别参考审批部门以及相应的审批文件,若无法办理或不想办理相关前置审批文件,您可以参考各省管局要求 ,能否修改经营范围或提供相应承诺书进行备案。

详情请参考:前置审批介绍

1.3 补充材料上传

补充材料上传页面

此处无特别需求可以暂时不填写,直接进入下一步:

如有特别需要提交的材料没有提交,腾讯云的初审团队会驳回申请,之后补充再次提交即可。

1.4 信息预览与提交备案

确认信息后提交即可

至此,我们网站备案的全部流程已经走完,等待相关管理部门审批即可。

审批时间根据地域性质会有所差异,大概在20天左右。

2. 开通微信H5支付

2.1 扫码登陆微信支付商户平台进入产品中心页面:

产品中心页面

选择H5支付,进入后选择申请开通,按需求填写表格和资料等待审批。

未开通时会显示申请开通字样

此处申请审批时间较长,请耐心等待。

期间我们可以做如下准备工作:

具体参考官方文档:H5支付接入前准备(直连模式)

https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_1.shtml

2.2 填写H5支付的域名

此处填写之前申请开通的域名

2.3 唤起支付

新建云函数如下:

注:此处云函数需创建API网关触发器,并关联申请好的域名:

详细配置见官方文档:https://cloud.tencent.com/document/product/583/12513

此处用到一个插件:wechatpay-axios-plugin

插件文档:https://github.com/TheNorthMemory/wechatpay-axios-plugin

平台证书密钥以及商户证书密钥等文件获取,也在文档中有详细说明,此处不在赘述。

代码语言:javascript
复制

//APIV3支付
const { Wechatpay } = require('wechatpay-axios-plugin');
const { readFileSync } = require('fs');
// 商户号,支持「普通商户/特约商户」或「服务商商户」
const merchantId = ''; //商户号
const appid = '' // APPID
// 「商户API证书」的「证书序列号」, 通过网页查看
const merchantCertificateSerial = '';
// 从本地文件中加载「商户API私钥」
const merchantPrivateKeyFilePath = '/key/apiclient_key.pem';
const merchantPrivateKeyInstance = readFileSync(merchantPrivateKeyFilePath);
// 「微信支付平台证书」的「证书序列号」,下载器下载后有提示`serial`序列号字段
const platformCertificateSerial = '';

// 从本地文件中加载「微信支付平台证书」,用来验证微信支付请求响应体的签名
const platformCertificateFilePath = '/key/wechatpay_573AB99XXXXXXXXXXXXXX.pem';
const platformCertificateInstance = readFileSync(platformCertificateFilePath);

// 创建支付实例
const wxpay = new Wechatpay({
mchid: merchantId,
serial: merchantCertificateSerial,
privateKey: merchantPrivateKeyInstance,
certs: { [platformCertificateSerial]: platformCertificateInstance, },
});

// 云函数入口函数
exports.main = async (event, context) => {
wxpay.v3.pay.transactions.h5
.post({
appid:appid,
mchid:merchantId,
description:"此处为唤起支付后的页面抬头,商户自拟",
out_trade_no:"AABBCC"+Date.now().toString(),//此处为商户端的订单号,自拟
notify_url:"XXXXX",// 此处为支付通知回调,非常重要,不要填错
amount:{
total:1,// 此处为消费金额,应由前端传入
currency:'CNY'
},
scene_info:{
payer_client_ip:"127.0.0.1",
h5_info:{
type:'Wap'
}
}
})
.then(({data: {h5_url}}) => console.info(h5_url))
.catch(console.error)
}

云函数目录结构:

唤起支付的云函数目录结构

其中key文件夹中存放商户的密钥等文件。

2.4 支付通知的回调函数

同样新建一个云函数,并创建API网关触发器,此处触发器的域名为上面的notify_url参数

代码语言:javascript
复制
//nodejs解密
const crypto = require('crypto');
//APIV3 nodejs模块
const { Wechatpay } = require('wechatpay-axios-plugin');
const { readFileSync } = require('fs');
//npm install wechatpay-axios-plugin
// 商户号
const merchantId = '';
// 商户证书序列号
const merchantCertificateSerial = '';
// 商户私钥路径
const merchantPrivateKeyFilePath = './merchant/apiclient_key.pem';
// 商户API私钥 PEM格式的文本字符串或者文件buffer
const merchantPrivateKeyInstance = readFileSync(merchantPrivateKeyFilePath);
// 平台证书
const platformCertificateFilePath = './merchant/wechatpay_XXXXX.pem';
const platformCertificateInstance = readFileSync(platformCertificateFilePath);
//平台证书公钥
const platformPubKeyFilePath = './merchant/wechatpay_XXXXXXXX.pem';
const platformPubKeyInstance = readFileSync(platformPubKeyFilePath);
// 平台证书序列号,下载器下载后有提示序列号字段,也可由命令行
const platformCertificateSerial = '';
//初始化
const wxpay = new Wechatpay({
mchid: merchantId,
serial: merchantCertificateSerial,
privateKey: merchantPrivateKeyInstance,
certs: { [platformCertificateSerial]: platformCertificateInstance, },
});

exports.main = async (event, context) => {
//接收支付通知结果
var body = JSON.parse(event.body);
// 解密 ciphertext字符 AEAD_AES_256_GCM算法,验证消息来源
let ciphertext = body.resource.ciphertext;
let nonce = body.resource.nonce;
let associated_data = body.resource.associated_data;
let apiv3key = "";//商户端的APIV3密钥,在网页中设置
ciphertext = Buffer.from(ciphertext, 'base64');
let authTag = ciphertext.slice(ciphertext.length - 16);
let data = ciphertext.slice(0, ciphertext.length - 16);
let decipher = crypto.createDecipheriv('aes-256-gcm', apiv3key, nonce);
decipher.setAuthTag(authTag);
decipher.setAAD(Buffer.from(associated_data));
let decoded = decipher.update(data, null, 'utf8');
decipher.final();
let payData = JSON.parse(decoded); //解密后的数据
console.log(payData)
var sub_mchid =payData.sub_mchid;
var transaction_id = payData.transaction_id;
var out_trade_no = payData.out_trade_no;

// 商户自行拟定后续逻辑
// TODO

// 收到回调后必须返回如下字段,否则通知会持续进行
return {   
    "code": "SUCCESS",
    "message": "成功"
}

};

至此功能已全部实现,感谢观看。