-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #75 from ifanrx/qq-payment
添加 QQ 小程序支付、QQ 网页扫码支付、QQ 加密信息解密等方法的支持
- Loading branch information
Showing
14 changed files
with
1,960 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
const HError = require('core-module/HError') | ||
|
||
const createDecryptDataFn = BaaS => (...params) => { | ||
const API = BaaS._config.API | ||
|
||
if (!validateParams(params)) { | ||
throw new HError(605) | ||
} | ||
|
||
let paramsObj = { | ||
encryptedData: params[0], | ||
iv: params[1] | ||
} | ||
|
||
return BaaS._baasRequest({ | ||
url: API.QQ.DECRYPT + params[2] + '/', | ||
method: 'POST', | ||
data: paramsObj, | ||
}).then(res => { | ||
return res.data | ||
}, err => { | ||
let code = err.code | ||
if (code === 403) throw new HError(403, 'QQ 解密插件未开启') | ||
throw err | ||
}) | ||
} | ||
|
||
const validateParams = (params) => { | ||
if (!(params instanceof Array) || params.length < 3) return false | ||
const requiredDataKeys = ['open-gid'] | ||
return requiredDataKeys.indexOf(params[2]) !== -1 | ||
} | ||
|
||
module.exports = function (BaaS) { | ||
BaaS.decryptData = createDecryptDataFn(BaaS) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
const BaaS = require('core-module/baas') | ||
const HError = require('core-module/HError') | ||
|
||
const API = BaaS._config.API | ||
|
||
const keysMap = { | ||
merchandiseSchemaID: 'merchandise_schema_id', // optional | ||
merchandiseRecordID: 'merchandise_record_id', // optional | ||
merchandiseSnapshot: 'merchandise_snapshot', // optional | ||
merchandiseDescription: 'merchandise_description', // required | ||
totalCost: 'total_cost', // required | ||
} | ||
|
||
const createPayFn = BaaS => params => { | ||
const API = BaaS._config.API | ||
let paramsObj = {} | ||
|
||
for (let key in params) { | ||
paramsObj[keysMap[key]] = params[key] | ||
} | ||
|
||
paramsObj.gateway_type = 'qpay' | ||
|
||
return BaaS._baasRequest({ | ||
url: API.PAY, | ||
method: 'POST', | ||
data: paramsObj, | ||
}).then(function (res) { | ||
let data = res.data || {} | ||
return new Promise((resolve, reject) => { | ||
qq.requestPayment({ | ||
package: data.package, | ||
success: function (res) { | ||
res.transaction_no = data.transaction_no | ||
res.trade_no = data.trade_no | ||
return resolve(res) | ||
}, | ||
fail: function (err) { | ||
if (err.errMsg == 'requestPayment:fail 用户取消') { | ||
reject(new HError(607)) | ||
} else { | ||
reject(new HError(608, err.errMsg)) | ||
} | ||
}, | ||
}) | ||
}) | ||
}) | ||
} | ||
|
||
module.exports = function (BaaS) { | ||
BaaS.pay = createPayFn(BaaS) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import test from 'ava'; | ||
import sinon from 'sinon' | ||
|
||
const moduleAlias = require('module-alias') | ||
moduleAlias.addAlias('core-module', __dirname + '../../../core') | ||
const decryptDataModule = require('../../sdk-file/src/qq/decryptData') | ||
const HError = require('core-module/HError') | ||
|
||
test.beforeEach(t => { | ||
t.context.BaaS = { | ||
_baasRequest: sinon.stub(), | ||
_config: { | ||
API: { | ||
QQ: { | ||
DECRYPT: 'decrypt-url/', | ||
}, | ||
}, | ||
}, | ||
} | ||
}) | ||
|
||
test('invoke encryptedData success', t => { | ||
decryptDataModule(t.context.BaaS) | ||
let encryptedData = 'encryptedData' | ||
let iv = 'iv' | ||
let type = 'open-gid' | ||
let data = { | ||
foo: 'foo', | ||
bar: 'bar', | ||
baz: 'baz', | ||
} | ||
t.context.BaaS._baasRequest.resolves({ | ||
status: 200, | ||
data, | ||
}) | ||
return t.context.BaaS.decryptData(encryptedData, iv, type).then(res => { | ||
t.deepEqual(res, data) | ||
t.is(t.context.BaaS._baasRequest.callCount, 1) | ||
t.deepEqual(t.context.BaaS._baasRequest.getCall(0).args, [{ | ||
data: { | ||
encryptedData: 'encryptedData', | ||
iv: 'iv', | ||
}, | ||
method: 'POST', | ||
url: 'decrypt-url/open-gid/', | ||
}]) | ||
}) | ||
}) | ||
|
||
test('invoke encryptedData fail (605)', t => { | ||
decryptDataModule(t.context.BaaS) | ||
let encryptedData = 'encryptedData' | ||
let iv = 'iv' | ||
let type = 'anyone' | ||
t.throws(() => { | ||
t.context.BaaS.decryptData(encryptedData, iv, type) | ||
}, new HError(605)) | ||
}) | ||
|
||
test('invoke encryptedData fail (403)', t => { | ||
decryptDataModule(t.context.BaaS) | ||
let encryptedData = 'encryptedData' | ||
let iv = 'iv' | ||
let type = 'open-gid' | ||
t.context.BaaS._baasRequest.rejects({code: 403}) | ||
return t.context.BaaS.decryptData(encryptedData, iv, type).catch(err => { | ||
t.deepEqual(err, new HError(403, 'QQ 解密插件未开启')) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import test from 'ava'; | ||
import sinon from 'sinon' | ||
|
||
const moduleAlias = require('module-alias') | ||
moduleAlias.addAlias('core-module', __dirname + '../../../core') | ||
const payModule = require('../../sdk-file/src/qq/pay') | ||
|
||
test('qq.pay', t => { | ||
let BaaS = { | ||
_baasRequest: sinon.stub().resolves({ | ||
data: { | ||
package: 'test-package', | ||
transaction_no: 'foo', | ||
trade_no: 'bar', | ||
}, | ||
}), | ||
_config: { | ||
API: { | ||
PAY: 'payment-url', | ||
}, | ||
}, | ||
} | ||
global.qq = { | ||
requestPayment: sinon.stub().callsFake(({success}) => { | ||
success({test: 'test-result'}) | ||
}) | ||
} | ||
payModule(BaaS) | ||
let params = { | ||
merchandiseSchemaID: 'merchandise_schema_id', // optional | ||
merchandiseRecordID: 'merchandise_record_id', // optional | ||
merchandiseSnapshot: 'merchandise_snapshot', // optional | ||
merchandiseDescription: 'merchandise_description', // required | ||
totalCost: 'total_cost', // required | ||
} | ||
return BaaS.pay(params).then(res => { | ||
t.deepEqual(res, { | ||
test: 'test-result', | ||
transaction_no: 'foo', | ||
trade_no: 'bar', | ||
}) | ||
t.is(global.qq.requestPayment.callCount, 1) | ||
t.is(BaaS._baasRequest.callCount, 1) | ||
t.is(global.qq.requestPayment.getCall(0).args[0].package, 'test-package') | ||
t.deepEqual(BaaS._baasRequest.getCall(0).args, [{ | ||
data: { | ||
gateway_type: 'qpay', | ||
merchandise_schema_id: 'merchandise_schema_id', | ||
merchandise_record_id: 'merchandise_record_id', | ||
merchandise_snapshot: 'merchandise_snapshot', | ||
merchandise_description: 'merchandise_description', | ||
total_cost: 'total_cost', | ||
}, | ||
method: 'POST', | ||
url: 'payment-url', | ||
}]) | ||
}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.