1/* 2* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15 16import CreateOrGet from './SingleInstanceHelper'; 17import cryptoFramework from '@ohos.security.cryptoFramework'; 18import payServer from './PayServer'; 19import util from '@ohos.util'; 20import resourceManager from '@ohos.resourceManager'; 21 22interface ProductInfo { 23 id: string, 24 name: string, 25 price: string, 26 img: string, 27} 28 29enum ErrorCode { 30 PLACE_ORDER_BODY_ERROR = 400, 31 PLACE_ORDER_ERROR = 401, 32} 33 34const TAG = 'MerchantServer'; 35const PRICE = 100; 36const TEXT_ENCODER = new util.TextEncoder(); 37const BASE64 = new util.Base64Helper(); 38const PLATFORM_NAME = '测试'; 39const SIGNER_INPUT = { data: TEXT_ENCODER.encodeInto('This is a test') }; 40const MERCHANT_PRI_KEY = 'MDECAQEEILoJbGqF0n4C+5KzSc8l6UFli3PAaH2+QYbe5sAxqCquoAoGCCqGSM49AwEH'; 41const PAY_PUB_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDFl9UiVDwrIUtTSFVaapGgH7v22lBqnm7kqOjUdNCaJE+eBVhCVT2K3KykPuE4xgtKej2ry+2Hme5MQaZZx7pxNkXE6P69y3m2Vbp1KnFgsXtWYldGA/vrmbXoDhKU4HdsPC4m+9vsELevFjuNyONMMMklF/l+3RdZ0gzRgOmJwIDAQAB'; 42const TEST_PRODUCTS: ProductInfo[] = Array.from({ length: 10 }, (_, i) => ({ 43 id: `${i + PRICE}`, 44 name: '80包手帕纸卫生抽纸家用', 45 price: '¥ 3.90', 46 img: 'app.media.icon' 47})); 48 49 50class MerchantServer { 51 private merchantKey: cryptoFramework.KeyPair; 52 private payKey: cryptoFramework.KeyPair; 53 54 public async placeAnOrder(body: ProductInfo): Promise<string> { 55 if (!body.id || !body.name || !body.price) { 56 throw { 57 code: ErrorCode.PLACE_ORDER_BODY_ERROR, 58 }; 59 } 60 let isOrderRight = false; 61 for (let product of TEST_PRODUCTS) { 62 if (product.id === body.id && product.name === body.name && product.price === body.price) { 63 isOrderRight = true; 64 } 65 } 66 if (!isOrderRight) { 67 throw { 68 code: ErrorCode.PLACE_ORDER_ERROR, 69 }; 70 } 71 72 // 下单信息加密传输给支付服务器,生成支付订单 73 let temStr = `platformName=${PLATFORM_NAME}&totalPrice=${body.price}&productName=${body.name}&productId=${body.id}`; 74 if (!this.payKey) { 75 let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2'); 76 this.payKey = await rsaGenerator.convertKey({ data: BASE64.decodeSync(PAY_PUB_KEY) }, null); 77 } 78 let cipher = cryptoFramework.createCipher('RSA1024|PKCS1'); 79 await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, this.payKey.pubKey, null); 80 let dataBlob = await cipher.doFinal({ data: TEXT_ENCODER.encodeInto(temStr) }); 81 let str: string = BASE64.encodeToStringSync(dataBlob.data); 82 let order = await payServer.generatePayOrder(str); 83 if (!this.merchantKey) { 84 let eccGenerator = cryptoFramework.createAsyKeyGenerator('ECC256'); 85 this.merchantKey = await eccGenerator.convertKey(null, { data: BASE64.decodeSync(MERCHANT_PRI_KEY) }); 86 } 87 let signer = cryptoFramework.createSign('ECC256|SHA256'); 88 await signer.init(this.merchantKey.priKey); 89 let signMessageBlob = await signer.sign(SIGNER_INPUT); 90 let result: string = order + '&signer=' + BASE64.encodeToStringSync(signMessageBlob.data); 91 return result; 92 } 93 94 public getProducts(): ProductInfo[] { 95 return TEST_PRODUCTS; 96 } 97} 98 99 100let mMerchantServer = CreateOrGet(MerchantServer, TAG); 101 102export default mMerchantServer as MerchantServer;