今年利用業余時間搞了個web應用,在支付環節卡住了,因為支付寶和微信都不支持個人收款,必須要有公司資質,沒辦法,只能google下看看是否有人和我遇到相同問題,果然有很多解決方案,研究了一個多禮拜,發現個人收款都是收費的,而且還不穩定,服務也非常差,問個問題半天甚至幾天后才有回答,最后沒辦法只能自己各種研究,搞出了一種真正免費的個人免簽支付方案(不需了解Andriod,不需了解后端開發,甚至不需要寫一行代碼),不敢獨享,現分享給大家,
基本原理
終極原理很簡單,就一句話:Android端應用將收到的個人微信的收款資訊通知后端服務,后端服務分析出誰支付了多少錢等資訊,然后通知開發者支付完成并自動發貨,
操作流程
1. 開發者上傳微信的個人收款碼到平臺,
2. 用戶發起請求支付服務,
3. 平臺回傳相匹配的收款二維碼并展示給用戶,
4. 用戶完成掃碼支付,
5. 安裝有收款微信的Android手機收到用戶完成支付的通知,
6. Android端應用將收款資訊通知后端服務,
7. 后端服務分析并校驗無誤后,通知開發者用戶已經完成支付,可以自動發貨了,
下面介紹利用「冰狐智能輔助」實作免費的個人免簽支付的方案,您只需要詳細案以下步驟操作,不需要寫一行代碼即可實作免費的個人免簽支付,分兩部分實作,一部分是移動端,負責捕獲收款資訊;另一部分是后端服務,負責決議并通知開發者支付結果,在之前請先免費注冊一個用戶,
構建移動端
- 下載「冰狐智能輔助」APP并安裝,安裝完成后請登錄,登錄時請按提示打開所有權限,具體下載地址和詳細安裝配置程序請參考這里,
- 登錄網頁,打開web頁面「移動端」/「移動端腳本」,新建一個名為“個人支付”的腳本,將如下JS腳本粘貼到這里并保存,
function main() {
while (true) {
}
}
function cbNotification(textList, className, packageName, event) {
for (var item of textList) {
if (item.includes('微信支付')) {
var arr = item.fetchNumber();
if (arr.length > 0) {
var ret = callMicroService('pay_notify', [rsUUID, 1, arr[arr.length - 1]]);
console.log('call ret:' + ret);
}
return true;
}
}
return false;
}
- 打開web頁面「移動端」/「我的設備」,找到剛才登錄的手機,然后選擇“編輯”按鈕,修改“默認腳本”為上面新建的“個人支付”腳本,
創建微服務腳本
微服務腳本用于實作后端的業務邏輯,比如:上傳和查看支付二維碼,查看支付訂單,通知開發者支付結果等功能,
打開web頁面「微服務」/「微服務腳本」新建如下腳本,并將對應的JS原始碼粘貼進去:
- pay_notify,用于處理支付資訊,并通知開發者支付結果,JS原始碼如下:
function main(uuid, type, price) {
var ret = false;
price = parseInt(price*100);
var key = uuid + price;
var orderId = cacheGet(key);
if (orderId) {
console.log('匹配到價格,可以通知了:' + orderId);
var data = dbQuery('order', '*', ['id=' + orderId]);
if (data && data.length == 1) {
var item = data[0];
// 通知 呼叫者
var bodyParams = {outTradeNo: item.outTradeNo, price: item.price / 100.0, realPrice: item.realPrice / 100.0};
var result = 2, postResult = httpPost(item.notifyUrl, bodyParams);
if (postResult && postResult.length > 0) {
if (postResult.status == 200 || postResult.status == 302) {
result = 1;
}
}
// change status
ret = dbUpdate('order', ['status=' + result], ['id=' + orderId]);
if (!ret) {
console.error('更新狀態失敗');
}
cacheRemove(key);
}
} else {
console.error('invalidate price:' + price);
}
return ret;
}
- add_price,用于添加支付二維碼,JS原始碼如下:
function main(payType, price, deviceId, file) {
price = parseInt(price*100);
var ret = false, qrCode = qrDecode(file.inputStream);
if (qrCode != '') {
var qRet = dbQuery('price', 'count(id) as count', [`userId='${rsOpenId}'`, `price=${price}`, `payType=${payType}`, `deviceId='${deviceId}'`]);
if (qRet[0].count > 0) {
ret = dbUpdate('price', [`qrCode='${qrCode}'`], [`price=${price}`, `payType=${payType}`, `deviceId='${deviceId}'`]);
} else {
var iRet = dbInsert('price', {userId:rsOpenId, price:price, payType:payType, deviceId:deviceId, qrCode:qrCode});
ret = iRet > 0;
}
}
return ret;
}
- query_price,用于查詢支付二維碼,JS原始碼如下:
function main(fetchCountOnly, conditions, startIndex, itemCount) {
var jsonConditions = JSON.parse(conditions), params = [`userId='${rsOpenId}'`];
for (var item of jsonConditions) {
if (item.name == 'query_type') {
var type = parseInt(item.value);
if (type > 0) {
params.push('payType=' + type);
}
}
}
if (fetchCountOnly) {
var qRet = dbQuery('price', 'count(id) as count', params);
return qRet[0].count;
} else {
var qRet = dbQuery('price', '*', params, '', startIndex, itemCount);
for (var item of qRet) {
item.price /= 100.0;
if (item.payType == 1) {
item.payType = '微信';
} else {
item.payType = '支付寶';
}
}
return qRet;
}
}
- unified_order,用于開發者請求支付,回傳支付二維碼,JS原始碼如下:
function main(payType, price, outTradeNo, notifyUrl, timeout = 120000) {
price = parseInt(price*100);
var ret = null, qrImage = '', realPrice = price;
var maxCount = 5, i = 0, anyRet = null, findAny = false;
while (i < maxCount) {
realPrice = price - i;
var qRet = dbQuery('price', '*', [`userId='${rsOpenId}'`, `payType=${payType}`, `price=${realPrice}`]);
if (qRet.length <= 0) {
if (!findAny) {
anyRet = dbQuery('price', '*', [`userId='${rsOpenId}'`, `payType=${payType}`, 'price=0']);
findAny = true;
}
qRet = anyRet;
}
if (qRet.length > 0) {
for (var item of qRet) {
var key = item.deviceId + realPrice;
var cache = cacheGet(key);
if (null == cache) {
lock('malloc_price');
cache = cacheGet(key);
if (null == cache) {
// 可以分配了
ret = dbInsert('order', {
userId: rsOpenId,
price: price,
realPrice: realPrice,
outTradeNo: outTradeNo,
deviceId: item.deviceId,
qrCode: item.qrCode,
notifyUrl: notifyUrl
});
}
if (null != ret) {
var image = qrEncode(item.qrCode);
qrImage = base64Encode(image);
cachePut(key, ret, 60000);
}
unlock('malloc_price');
if (null != ret) {
break;
}
}
}
}
if (null != ret) {
break;
}
++i;
}
if (null == ret) {
console.error('unified failed');
} else {
return {payTye: payType, price: price, realPrice: realPrice, qrImageData: qrImage, timeout: timeout};
}
return {};
}
- common,一些通用的函式,JS原始碼如下:
function deletePrice(item) {
var id = item.id;
return dbDelete('price', [`id=${id}`]);
}
function deleteOrder(item) {
var id = item.id;
return dbDelete('order', [`id=${id}`]);
}
function getDevice(includeAll=false) {
var list = deviceList(rsOpenId);
var result = [];
if (includeAll) {
result.push({name: '全部', value: ''});
}
for (var item of list) {
result.push({name: item.name, value: item.uuid});
}
return result;
}
創建移動端介面
移動端介面用于「冰狐智能輔助」APP端腳本呼叫,在這里主要用于手機端通知后端服務支付相關資訊,參考檔案
- 打開web頁面「微服務」/「移動端介面」,新建名為“pay_notify”的介面,選擇“pay_notify”腳本,
創建服務端介面
服務端介面用于第三方服務呼叫「冰狐智能輔助」的后端功能,這里主要用于開發者在自己的后端服務中呼叫生成訂單的介面,參考檔案
- 打開web頁面「微服務」/「服務端介面」,新建名為”unified_order”的介面,選擇“unified_order”腳本,
創建二維碼價格資料庫
價格資料庫用于存放開發者上傳的價格二維碼資訊,
- 打開web頁面「微服務」/「資料庫」,新建名為“price”的資料庫,
- 選擇“模式” / “列原始碼”按鈕,將如下列原始碼粘貼進去并確認修改,
[{
"type": "tinyint",
"name": "payType",
"default": "1",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}, {
"name": "unsigned",
"value": false,
"description": "無符號"
}]
}, {
"type": "varchar(45)",
"name": "deviceId",
"default": "''",
"options": [{
"name": "not null",
"value": true,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}, {
"type": "varchar(128)",
"name": "qrCode",
"default": "''",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}, {
"type": "int",
"name": "price",
"default": "0",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}, {
"name": "unsigned",
"value": false,
"description": "無符號"
}]
}, {
"type": "varchar(45)",
"name": "userId",
"default": "''",
"options": [{
"name": "not null",
"value": true,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}][{
"name": "支付型別",
"id": "payType",
"type": "select",
"defaultValue": "微信:1,支付寶:2",
"description": ""
}, {
"name": "價格",
"id": "price",
"type": "float",
"defaultValue": "",
"description": ""
}, {
"name": "設備",
"id": "deviceId",
"type": "select",
"defaultValue": "{\"name\":\"get_device\", \"params\":[], \"isDev\":true}",
"description": ""
}, {
"name": "二維碼圖片",
"id": "file",
"type": "file",
"defaultValue": "",
"description": ""
}]
- 選擇“索引”按鈕,選擇“索引原始碼”,將如下列原始碼粘貼進去并確認修改,
[{
"indexName": "userId",
"columnsName": "userId"
}]
創建訂單資料庫
訂單資料庫用于存放訂單資料,
- 打開web頁面「微服務」/「資料庫」,新建名為“order”的資料庫,
- 選擇“模式”按鈕,選擇“列原始碼”,將如下列原始碼粘貼進去并確認修改,
[{
"type": "char(45)",
"name": "userId",
"default": "''",
"options": [{
"name": "not null",
"value": true,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}, {
"type": "char(45)",
"name": "deviceId",
"default": "''",
"options": [{
"name": "not null",
"value": true,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}, {
"type": "char(128)",
"name": "outTradeNo",
"default": "''",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}, {
"type": "tinyint",
"name": "payType",
"default": "1",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}, {
"name": "unsigned",
"value": false,
"description": "無符號"
}]
}, {
"type": "int",
"name": "price",
"default": "",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}, {
"name": "unsigned",
"value": false,
"description": "無符號"
}]
}, {
"type": "int",
"name": "realPrice",
"default": "",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}, {
"name": "unsigned",
"value": false,
"description": "無符號"
}]
}, {
"type": "char(128)",
"name": "notifyUrl",
"default": "''",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}, {
"type": "char(128)",
"name": "qrCode",
"default": "''",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}, {
"type": "tinyint",
"name": "status",
"default": "0",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}, {
"name": "unsigned",
"value": false,
"description": "無符號"
}]
}, {
"type": "timestamp",
"name": "time",
"default": "CURRENT_TIMESTAMP",
"options": [{
"name": "not null",
"value": false,
"description": "不為空"
}, {
"name": "unique",
"value": false,
"description": "不重復"
}]
}]
- 選擇“索引”按鈕,選擇“索引原始碼”,將如下列原始碼粘貼進去并確認修改,
[{
"indexName": "userId",
"columnsName": "userId"
}, {
"indexName": "deviceId",
"columnsName": "deviceId"
}]
創建二維碼錄入服務
用于開發者錄入價格二維碼,
- 打開web頁面「微服務」/「資料錄入服務」,新建名為“上傳價格”的服務,選擇”add_price”腳本,
- 選擇“引數”按鈕,選擇“引數原始碼”,將如下引數原始碼粘貼進去并確認修改,
[{
"name": "支付型別",
"id": "payType",
"type": "select",
"defaultValue": "微信:1,支付寶:2",
"description": ""
}, {
"name": "價格",
"id": "price",
"type": "float",
"defaultValue": "",
"description": ""
}, {
"name": "設備",
"id": "deviceId",
"type": "select",
"defaultValue": "{\"scriptName\":\"common\",\"functionName\":\"getDevice\"}",
"description": ""
}, {
"name": "二維碼圖片",
"id": "file",
"type": "file",
"defaultValue": "",
"description": ""
}]
創建價格查詢服務
用于開發者查詢已經錄入的價格二維碼資訊,
- 打開web頁面「微服務」/「資料查詢服務」,新建名為“查詢價格”的服務,選擇”query_price”腳本,
- 選擇“查詢引數”按鈕,選擇“引數原始碼”,將如下引數原始碼粘貼進去并確認修改,
[{
"name": "支付型別",
"id": "query_type",
"type": "select",
"defaultValue": "微信:1,支付寶:2",
"description": ""
}]
- 選擇“列”按鈕,選擇“列原始碼”,將如下列原始碼粘貼進去并確認修改,
[{
"name": "支付型別",
"id": "payType"
}, {
"name": "價格",
"id": "price"
}, {
"name": "設備ID",
"id": "deviceId"
}, {
"name": "二維碼",
"id": "qrCode"
}]
- 選擇“資料操作”按鈕,選擇“操作原始碼”,將如下操作原始碼粘貼進去并確認修改,
[{
"name": "洗掉",
"id": "delete",
"scriptId": "5",
"scriptName": "common",
"functionName": "deletePrice"
}]
創建訂單查詢服務
用于開發者查詢歷史訂單資訊,
- 打開web頁面「微服務」/「資料查詢服務」,新建名為“查詢訂單”的服務,選擇”query_order”腳本,
- 選擇“查詢引數”按鈕,選擇“引數原始碼”,將如下引數原始碼粘貼進去并確認修改,
[{
"name": "設備",
"id": "deviceId",
"type": "select",
"defaultValue": "{\"scriptName\":\"common\",\"functionName\":\"getDevice\", \"params\":[true]}\t",
"description": ""
}]
- 選擇“列”按鈕,選擇“列原始碼”,將如下列原始碼粘貼進去并確認修改,
[{
"name": "設備",
"id": "deviceId"
}, {
"name": "交易NO",
"id": "outTradeNo"
}, {
"name": "支付型別",
"id": "payType"
}, {
"name": "價格",
"id": "price"
}, {
"name": "支付價格",
"id": "realPrice"
}, {
"name": "狀態",
"id": "status"
}, {
"name": "時間",
"id": "time"
}]
- 選擇“資料操作”按鈕,選擇“操作原始碼”,將如下操作原始碼粘貼進去并確認修改,
[{
"name": "洗掉",
"id": "delete",
"scriptId": "5",
"scriptName": "common",
"functionName": "deleteOrder"
}]
啟動手機端程式
打開手機端「冰狐智能輔助」APP,點擊“點擊這里啟動設備”啟動設備,
上傳微信支付二維碼
- 打開web頁面「微服務」/「資料錄入服務」,找到“上傳價格”服務,然后點擊“執行”,在彈出的對話框中填入資料、上傳微信的支付二維碼圖片,最后點擊“執行”,
?
- 打開web頁面「微服務」/「資料查詢服務」,找到“查詢價格”服務,然后點擊“查詢“按鈕查詢已經上傳的價格二維碼,
?
支付測驗
- 用postman模擬第三方后端服務呼叫介面,生成訂單,
https://aznfz.com/api/call_micro_service?clientKey=xxxxx&accessToken=yyyyy&name=unified_order&isDev=true¶ms=zzz,詳細請參考檔案:https://aznfz.com/document/open_api#call - 呼叫后就生成了對應的支付訂單,可在「微服務」/「資料查詢服務」,“訂單查詢”服務中,點擊“查詢”按鈕查詢訂單,
?
- 用其他微信向收款微信支付一筆費用,完成后,再次查詢訂單,看看是否完成,
總結
本文介紹了一種基于「冰狐智能輔助」系統實作的、不需了解Andriod、不需了解后端開發、甚至不需要撰寫一行代碼、免費的、個人免簽支付方案和具體實作細節,有任何問題,歡迎評論留言,大家一起討論😊!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/340465.html
標籤:其他
