From 49d582ef0616641d1283fff473a286bd08f98247 Mon Sep 17 00:00:00 2001 From: qiaoxin Date: Wed, 12 May 2021 19:20:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B4=BB=E5=8A=A8=EF=BC=9A=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=AE=9D=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/order/handler/orderHandler.ts | 41 ++++-- game-server/app/services/pay/aliPay.ts | 93 +++++++++++++ game-server/package-lock.json | 128 ++++++------------ game-server/package.json | 1 + key/alipay/rsa_private_key.pem | 3 + key/alipay/rsa_public_key.pem | 3 + shared/db/UserOrder.ts | 9 ++ 7 files changed, 178 insertions(+), 100 deletions(-) create mode 100644 game-server/app/services/pay/aliPay.ts create mode 100644 key/alipay/rsa_private_key.pem create mode 100644 key/alipay/rsa_public_key.pem diff --git a/game-server/app/servers/order/handler/orderHandler.ts b/game-server/app/servers/order/handler/orderHandler.ts index b1281a0f9..6bd7063da 100644 --- a/game-server/app/servers/order/handler/orderHandler.ts +++ b/game-server/app/servers/order/handler/orderHandler.ts @@ -7,6 +7,7 @@ import { dicRMB } from '../../../pubUtils/dictionary/DicRMB'; import { UserOrderModel } from '../../../db/UserOrder'; import _ = require('underscore'); import { applyOrderWX, checkOrderWX } from '../../../services/pay/weixinPay'; +import { applyOrderALI, checkOrderALI } from '../../../services/pay/aliPay'; export default function (app: Application) { return new orderHandler(app); @@ -50,7 +51,6 @@ export class orderHandler { switch (payType) { case PAY_TYPE.WX: { - //生成订单号 let weixinOrder = await applyOrderWX(localOrderID, price * 100, message); if (weixinOrder.code == 0) { console.log('微信下单失败') @@ -62,6 +62,14 @@ export class orderHandler { } case PAY_TYPE.ALI: { + let aliOrder = await applyOrderALI(localOrderID, price, message); + if (aliOrder.code == 0) { + console.log('支付宝下单失败') + return resResult(STATUS.APPLY_ORDER_ERROR); + } + sdkOrderInfo = aliOrder.data; + orderID = aliOrder.data;//支付宝订单 + break; } @@ -153,6 +161,20 @@ export class orderHandler { } case PAY_TYPE.ALI: { + let aliResult = await checkOrderALI(localOrderID); + if (aliResult.code == 0) { + console.log('支付宝订单查询失败') + return resResult(STATUS.ORDER_ERROR); + } + if (parseInt(aliResult.data.total_amount) != price) { + console.log('订单价格错误') + return resResult(STATUS.PRICE_ERROR); + } + if (aliResult.data.trade_status != "TRADE_SUCCESS") { + return resResult(STATUS.NO_PAY); + } + let aliOrderID = aliResult.data.trade_no; + await UserOrderModel.saveOrderID(roleId, localOrderID, aliOrderID); break; } @@ -166,20 +188,13 @@ export class orderHandler { } //订单成功 - let isSuccess = true; - if (isSuccess) { - orderInfo = await UserOrderModel.success(roleId, localOrderID); - if (orderInfo) { - //结算奖励 - console.log('结算完成', localOrderID) - return resResult(STATUS.SUCCESS, Object.assign({})); - } - } else { - let message = '订单校验失败'; - orderInfo = await UserOrderModel.fail(roleId, localOrderID, message); + orderInfo = await UserOrderModel.success(roleId, localOrderID); + if (orderInfo) { + //结算奖励 + console.log('结算完成', localOrderID) + return resResult(STATUS.SUCCESS, Object.assign({})); } - return resResult(STATUS.DUPLICATE_ORDER); } diff --git a/game-server/app/services/pay/aliPay.ts b/game-server/app/services/pay/aliPay.ts new file mode 100644 index 000000000..0c3c79483 --- /dev/null +++ b/game-server/app/services/pay/aliPay.ts @@ -0,0 +1,93 @@ + +import path = require('path'); +import fs = require('fs'); +const Alipay = require('alipay-mobile').default +/* +包名:com.bantu.sgzzyz +APPID:2021002142639438 +*/ + +//notify_url: 异步通知url +//app_id: 开放平台 appid +//appPrivKeyFile: 你的应用私钥 +//alipayPubKeyFile: 蚂蚁金服公钥 +const config = { + app_id: '2021002142639438', + appPrivKeyFile: fs.readFileSync(path.resolve(__dirname, '../../../../../key/alipay/rsa_private_key.pem')), + alipayPubKeyFile: fs.readFileSync(path.resolve(__dirname, '../../../../../key/alipay/rsa_public_key.pem')) +} + + +const service = new Alipay(config) + +/** + * 支付宝下单 + * + * @param {number} price 订单总金额,单位为元,精确到小数点后两位 + * @param {string} message 商品信息 + * @param {string} localOrderID 本地订单号 + * + */ +export async function applyOrderALI(localOrderID: string, price: number, message: string) { + const data = { + subject: message, + out_trade_no: localOrderID, + total_amount: price.toFixed(2).toString() + } + console.log('applyOrderALI :', data) + let result = await service.createOrder(data) + + // { code: 0, + // message: '请求成功', + // data: + // 'app_id=2021002142639438&biz_content=%7B%22subject%22%3A%22%E8%B5%B5%E4%BA%91%E4%BC%A0%E8%B4%AD%E4%B9%B0%E5%85%83%E5%AE%9D60%22%2C%22out_trade_no%22%3A%22bwnNLGfdCylflxKf54bEpcwyEbq7xygp%22%2C%22total_amount%22%3A%226.00%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%7D&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2×tamp=2021-05-12%2018%3A40%3A25&version=1.0&sign=S4U6JzSUiCSMvAbXeiJ2m2AQ%2BfCSr4VE4VNN9QEZtplgWIO51HIGhL24BpR4aj7mMfWO%2BqaWQnU0Fe8Uki960smBdj0%2FDpuztA7%2BIBWHK1Qj69%2FLhDNLoHZgO41jQJjIOVI0gWt1KaDlG2%2B52ghswqcZN%2FkFLwfMZCMEph3eg3aofq1mmwRbqAh8Sepoy9nCd24CmMUIbNe%2FmcxVg3xvYcWXnneWWHu%2FFbnaeZtynoHVhXqqhjFZSrxdk8lo5qyTXkE1ZoUrhJz918E2rArwzZeUL09ncPshHHvX6AygXp5BtV4clwTY0OY5yzOEXboluR5YmSaVXn0VkTWJZCTWTQ%3D%3D' + // } + console.log('applyOrderALI result: ', result) + if (result.code == 0) { + return { code: 1, data: result.data }; + } + return { code: 0, data: JSON.stringify(result) }; +} + + + +/** + * 支付宝查询支付结果 + * + * @param {number} serverId 区Id + * @param {string} roleId 角色Id + * @param {string} localOrderID 本地订单号 + * + */ +export async function checkOrderALI(localOrderID: string) { + let data = { + out_trade_no: localOrderID, + } + console.log('checkOrderALI :', data) + + let result = await service.queryOrder(data) + console.log('checkOrderALI result: ', result) + // { + // 0|app | code: '0', + // 0|app | data: { + // 0|app | code: '10000', + // 0|app | msg: 'Success', + // 0|app | buyer_logon_id: '525***@qq.com', + // 0|app | buyer_pay_amount: '0.00', + // 0|app | buyer_user_id: '2088302819007765', + // 0|app | invoice_amount: '0.00', + // 0|app | out_trade_no: 'JbyWyR1SIVIw9ArxvHAgte6tmnIzSRea', + // 0|app | point_amount: '0.00', + // 0|app | receipt_amount: '0.00', + // 0|app | send_pay_date: '2019-09-29 18:32:13', + // 0|app | total_amount: '1.00', + // 0|app | trade_no: '2019092922001407760553648380', + // 0|app | trade_status: 'TRADE_SUCCESS' + // 0|app | }, + // 0|app | message: 'success' + // 0|app | } + if ((result.code == '0') && (result.message == "success")) { + return { code: 1, data: result.data }; + } + return { code: 0, data: JSON.stringify(result) }; +} \ No newline at end of file diff --git a/game-server/package-lock.json b/game-server/package-lock.json index fd274286a..e9fc458f3 100644 --- a/game-server/package-lock.json +++ b/game-server/package-lock.json @@ -224,6 +224,16 @@ "debug": "4" } }, + "alipay-mobile": { + "version": "4.0.2", + "resolved": "https://registry.nlark.com/alipay-mobile/download/alipay-mobile-4.0.2.tgz", + "integrity": "sha1-dGQCRAgLpSlJf76vhqwGKGUaFs4=", + "requires": { + "joi": "^14.3.1", + "moment": "^2.19.3", + "urllib": "^2.21.1" + } + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -404,71 +414,6 @@ "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz", "integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=" }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz", - "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566551397&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz", - "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz", - "integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433856030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz", - "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.nlark.com/raw-body/download/raw-body-2.4.0.tgz", - "integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - } - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz", @@ -1340,6 +1285,11 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "hoek": { + "version": "6.1.3", + "resolved": "https://registry.npm.taobao.org/hoek/download/hoek-6.1.3.tgz", + "integrity": "sha1-c7fTOVLgH+J6OLBFcpS3ndjaJCw=" + }, "http-errors": { "version": "1.7.3", "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.3.tgz", @@ -1522,6 +1472,14 @@ "resolved": "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npm.taobao.org/isemail/download/isemail-3.2.0.tgz", + "integrity": "sha1-WTEKAhkxqfsGu7UeFVzgs/I2gyw=", + "requires": { + "punycode": "2.x.x" + } + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1532,6 +1490,16 @@ "resolved": "https://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "joi": { + "version": "14.3.1", + "resolved": "https://registry.npm.taobao.org/joi/download/joi-14.3.1.tgz?cache=0&sync_timestamp=1612746391586&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjoi%2Fdownload%2Fjoi-14.3.1.tgz", + "integrity": "sha1-FkomLsC4VUZuDDXuoqiFrotscDw=", + "requires": { + "hoek": "6.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz", @@ -1667,11 +1635,6 @@ "resolved": "https://registry.npm.taobao.org/make-error/download/make-error-1.3.6.tgz?cache=0&sync_timestamp=1582105759247&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmake-error%2Fdownload%2Fmake-error-1.3.6.tgz", "integrity": "sha1-LrLjfqm2fEiR9oShOUeZr0hM96I=" }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.nlark.com/media-typer/download/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, "memory-pager": { "version": "1.5.0", "resolved": "https://registry.npm.taobao.org/memory-pager/download/memory-pager-1.5.0.tgz", @@ -2310,14 +2273,6 @@ "object-keys": "^1.1.1" } }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz?cache=0&sync_timestamp=1614930634590&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fon-finished%2Fdownload%2Fon-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", @@ -3325,6 +3280,14 @@ "resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz", "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=" }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npm.taobao.org/topo/download/topo-3.0.3.tgz", + "integrity": "sha1-1aZ/suaTB+vusIQC7Coqb1962Vw=", + "requires": { + "hoek": "6.x.x" + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -3403,15 +3366,6 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz", - "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, "typescript": { "version": "3.9.7", "resolved": "https://registry.npm.taobao.org/typescript/download/typescript-3.9.7.tgz?cache=0&sync_timestamp=1596790269694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-3.9.7.tgz", diff --git a/game-server/package.json b/game-server/package.json index 199445782..b36ea4463 100644 --- a/game-server/package.json +++ b/game-server/package.json @@ -26,6 +26,7 @@ "@types/redis": "^2.8.25", "@types/request-promise": "^4.1.47", "@types/underscore": "^1.10.24", + "alipay-mobile": "^4.0.2", "bcrypt": "^5.0.0", "bluebird": "^3.5.1", "chai": "^4.2.0", diff --git a/key/alipay/rsa_private_key.pem b/key/alipay/rsa_private_key.pem new file mode 100644 index 000000000..00f5666d2 --- /dev/null +++ b/key/alipay/rsa_private_key.pem @@ -0,0 +1,3 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAqhFp/IbUVIqLSCGbC/TDbEBzALTf5Tr0Be9dTmOz+nJO73H5VUhT2ADDFRxDtsn3Nannwer0B/kK40xGiYj7tv+uCIwNulr4aOkA7t+faDu01atbIroJb/6TGe8I33JkRWlW0O2IG0P3ZMLRp28yj0zmmxdeUpQomdy3AEcSSL9HKkRniYuSviud7FjOm/oa3mjUjAxmDVeZYpqAhSPT2rhpaIC47PBmEIfYjrH5QsszgxEyrOFq84mBtYFSJp0pHYp/7+p9olmxHO+R3OoPIWCrjJ653Z0AFuSNARNLAIpgKfTnXqenm+KC2cHEBRkHU971kOWTlecOGr/wrOBrrQIDAQABAoIBAQCoX51C+mn1WUUUINFUQPvJjPVO2cRhOsClr5n9JhDl/43O2lQz7uuziu2ZVOZlbgdmBdUB1A/OZO42oymiuRAc2X3/0Ek3GyGdHDJkTNmRZKtgb8pG01DMpIoWvuVV8/b6EZR2PPTnqZ6hD5Bp6FlyLnyRR82GjFC2JCK6D6M2iSkDr8GwC7Snw8dj+nM8VmnmS4jfDVX7M7sNJ+/hQwYaP4G6YLf0JzzxzZJg0nqUComQP5duUWTQO+9yVgFPMa28VxcEBb8xJ2lhYSN5ReBYPhftS46v6OGiPRZSEJOYyWh2Zkj5MUS2jfyuYlUSF2Hm+syUdaK1FVxnJrHnPtwBAoGBAOy3WrqmhOpg4+H5MHj3t7bETVoHNyAQ4QT40eYe7BH1QikFgoVtBKvbgK/9XBcmNWf3fJtoNiPA4HwL31RFm5SX24iqZ+OPnE2si1V2lawSQqcF5yTzFR1CEooKVMOEb36QL8zacs8o30so5BTZ4YCnwpVDnrtdZxV3nNmWIzZBAoGBALfsIaIHkldrp+nADFMW+OayAOesP3NfhSdG8N/uGvEkhT6YjCaycTUQ5Jxl8oWmlCG0OvdTZ/yvQZqWqDYS7b0O56A4sTGFjzdPNTPB6EYXODcUFCCi6er2aNaKc9OQgdaR3jsj0RyIl3oNgp/Lo6YNrCbr4JCPROSv0EcfIdJtAoGBANmWXLavNAQBFdd0Z+L5yQwd+wAjG7/E5CHe2YnOqK6FI9BzORuOLzoNpYefuxOoUnUDn612KDXLKE292AYtiaoXwHsqMB6TtlgLn3Pqcf/eNRg0K9jh/GmNf18Vyf6CcL4EqXuC3P+hEUeUCbtE36yUCB+OLY0KeSPZc/rpr+pBAoGBAIpBBkc2SdtNIbukkZ8j9ZX02JlN8aRYeU89FHRAGCCMw1x6b1/nYxHw0Oh/+f5daZysTmb8W36mfzolZey/7dXgDl1yQEBplW6OK//sEx4c9jTw8vBVhmEJOWWMTeULC46vt83c7qP0SWmGHlrgSPPZ8z6OsQ/5omAFiRrtXA9BAoGAOfjbJPSvfFeE9k16o2BUcZFmkN5xiKnausxJNJCCP/TzMX7urXimRFY6Y7+xSnitJovQUubDNjQsp4bfrlt41JO5ejcy4bQr2pQr4S5M+Hh5UOliwDS5Bt5Yy+5LLBWhQ0vyWdD5Ej+QNm2PFaBDqY+yoouEWNBY54uGjTbgRNI= +-----END RSA PRIVATE KEY----- diff --git a/key/alipay/rsa_public_key.pem b/key/alipay/rsa_public_key.pem new file mode 100644 index 000000000..8fb373fa4 --- /dev/null +++ b/key/alipay/rsa_public_key.pem @@ -0,0 +1,3 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqhFp/IbUVIqLSCGbC/TDbEBzALTf5Tr0Be9dTmOz+nJO73H5VUhT2ADDFRxDtsn3Nannwer0B/kK40xGiYj7tv+uCIwNulr4aOkA7t+faDu01atbIroJb/6TGe8I33JkRWlW0O2IG0P3ZMLRp28yj0zmmxdeUpQomdy3AEcSSL9HKkRniYuSviud7FjOm/oa3mjUjAxmDVeZYpqAhSPT2rhpaIC47PBmEIfYjrH5QsszgxEyrOFq84mBtYFSJp0pHYp/7+p9olmxHO+R3OoPIWCrjJ653Z0AFuSNARNLAIpgKfTnXqenm+KC2cHEBRkHU971kOWTlecOGr/wrOBrrQIDAQAB +-----END PUBLIC KEY----- diff --git a/shared/db/UserOrder.ts b/shared/db/UserOrder.ts index cfabf165e..7eb18d9a3 100644 --- a/shared/db/UserOrder.ts +++ b/shared/db/UserOrder.ts @@ -28,6 +28,15 @@ export default class UserOrder extends BaseModel { @prop({ required: true }) message: string; // 信息 + + //保存平台订单号 + public static async saveOrderID(roleId: string, localOrderID: string, aliOrderID: string) { + let result: UserOrderModelType = await UserOrderModel.findOneAndUpdate({ roleId, localOrderID }, + { $set: { orderID: aliOrderID } }, + { new: true }).lean(true); + return result; + } + //校验订单 public static async check(roleId: string, localOrderID: string, message: string = '') { let result: UserOrderModelType = await UserOrderModel.findOneAndUpdate({ roleId, localOrderID, state: { $ne: ORDER_STATE.RESULT_SUCCESS } },