【发布时间】:2020-10-13 23:33:55
【问题描述】:
您可以想象,stripe 和 authorize.net 以及其他支付网关服务提供的 api 出于安全原因只能通过服务器端访问。目前,Authorize.net 的文档允许我创建一个快速节点应用程序,然后运行命令 node charge-credit-card.js(它可以工作并从他们的 api 获得 200 响应)我的问题是两个部分。如何将我的服务器目录(在本段下方的图像中恰当地命名为 AuthorizePaymentNode)与我的 angular src 应用程序目录(在图像中恰当地命名为 FoodOrderingApp)连接以在前端收集卡信息,以便我可以处理信用卡从头到尾?其次,假设我让它在开发中工作,我如何以及在哪里上传我的 AuthorizePaymentNode 目录以及我的 FoodOrderingApp 以便两者一起工作。我是按照我朋友的建议在两个不同的地方完成,还是可以一次在一个地方完成?
[https://i.stack.imgur.com/ibUDr.png][1]
charge-credit-card.js(运行节点charge-credit-card.js时就像一个魅力)
var ApiContracts = require('authorizenet').APIContracts; var ApiControllers = require('authorizenet').APIControllers; var SDKConstants = require('authorizenet').Constants; var utils = require('./utils.js'); var constants = require('./constants.js'); 函数chargeCreditCard(回调){ var MerchantAuthenticationType = new ApiContracts.MerchantAuthenticationType(); MercerAuthenticationType.setName(constants.apiLoginKey); MercerAuthenticationType.setTransactionKey(constants.transactionKey); var creditCard = new ApiContracts.CreditCardType(); creditCard.setCardNumber('4242424242424242'); creditCard.setExpirationDate('0822'); 信用卡.setCardCode('999'); var paymentType = new ApiContracts.PaymentType(); paymentType.setCreditCard(creditCard); var orderDetails = new ApiContracts.OrderType(); orderDetails.setInvoiceNumber('INV-12345'); orderDetails.setDescription('产品描述'); var tax = new ApiContracts.ExtendedAmountType(); tax.setAmount('4.26'); tax.setName('level2 税名'); tax.setDescription('level2 tax'); var duty = new ApiContracts.ExtendedAmountType(); 职责.setAmount('8.55'); duty.setName('职务名称'); duty.setDescription('职责描述'); var shipping = new ApiContracts.ExtendedAmountType(); shipping.setAmount('8.55'); shipping.setName('运输名称'); shipping.setDescription('运输描述'); var billTo = new ApiContracts.CustomerAddressType(); billTo.setFirstName('艾伦'); billTo.setLastName('约翰逊'); billTo.setCompany('Souveniropolis'); billTo.setAddress('14 Main Street'); billTo.setCity('山核桃泉'); billTo.setState('TX'); billTo.setZip('44628'); billTo.setCountry('美国'); var shipTo = new ApiContracts.CustomerAddressType(); shipTo.setFirstName('China'); shipTo.setLastName('Bayles'); shipTo.setCompany('茶用百里香'); shipTo.setAddress('12 Main Street'); shipTo.setCity('山核桃泉'); shipTo.setState('TX'); shipTo.setZip('44628'); shipTo.setCountry('USA'); var lineItem_id1 = new ApiContracts.LineItemType(); lineItem_id1.setItemId('1'); lineItem_id1.setName('花瓶'); lineItem_id1.setDescription('戛纳标志'); lineItem_id1.setQuantity('18'); lineItem_id1.setUnitPrice(45.00); var lineItem_id2 = new ApiContracts.LineItemType(); lineItem_id2.setItemId('2'); lineItem_id2.setName('vase2'); lineItem_id2.setDescription('戛纳标志2'); lineItem_id2.setQuantity('28'); lineItem_id2.setUnitPrice('25.00'); var lineItemList = []; lineItemList.push(lineItem_id1); lineItemList.push(lineItem_id2); var lineItems = new ApiContracts.ArrayOfLineItem(); lineItems.setLineItem(lineItemList); var userField_a = new ApiContracts.UserField(); userField_a.setName('A'); userField_a.setValue('Aval'); var userField_b = new ApiContracts.UserField(); userField_b.setName('B'); userField_b.setValue('Bval'); var userFieldList = []; userFieldList.push(userField_a); userFieldList.push(userField_b); var userFields = new ApiContracts.TransactionRequestType.UserFields(); userFields.setUserField(userFieldList); var transactionSetting1 = new ApiContracts.SettingType(); transactionSetting1.setSettingName('duplicateWindow'); transactionSetting1.setSettingValue('120'); var transactionSetting2 = new ApiContracts.SettingType(); transactionSetting2.setSettingName('recurringBilling'); transactionSetting2.setSettingValue('false'); var transactionSettingList = []; transactionSettingList.push(transactionSetting1); transactionSettingList.push(transactionSetting2); var transactionSettings = new ApiContracts.ArrayOfSetting(); transactionSettings.setSetting(transactionSettingList); var transactionRequestType = new ApiContracts.TransactionRequestType(); transactionRequestType.setTransactionType(ApiContracts.TransactionTypeEnum.AUTHCAPTURETRANSACTION); transactionRequestType.setPayment(paymentType); transactionRequestType.setAmount(utils.getRandomAmount()); transactionRequestType.setLineItems(lineItems); transactionRequestType.setUserFields(userFields); transactionRequestType.setOrder(orderDetails); transactionRequestType.setTax(tax); transactionRequestType.setDuty(duty); transactionRequestType.setShipping(运费); transactionRequestType.setBillTo(billTo); transactionRequestType.setShipTo(shipTo); transactionRequestType.setTransactionSettings(transactionSettings); var createRequest = new ApiContracts.CreateTransactionRequest(); createRequest.setMerchantAuthentication(merchantAuthenticationType); createRequest.setTransactionRequest(transactionRequestType); //漂亮的打印请求 console.log(JSON.stringify(createRequest.getJSON(), null, 2)); var ctrl = new ApiControllers.CreateTransactionController(createRequest.getJSON()); //默认为沙盒 //ctrl.setEnvironment(SDKConstants.endpoint.production); ctrl.execute(函数(){ var apiResponse = ctrl.getResponse(); var response = new ApiContracts.CreateTransactionResponse(apiResponse); //漂亮的打印响应 console.log(JSON.stringify(response, null, 2)); 如果(响应!= null){ if(response.getMessages().getResultCode() == ApiContracts.MessageTypeEnum.OK){ if(response.getTransactionResponse().getMessages() != null){ console.log('成功创建事务,事务 ID: ' + response.getTransactionResponse().getTransId()); console.log('响应码:' + response.getTransactionResponse().getResponseCode()); console.log('消息代码:' + response.getTransactionResponse().getMessages().getMessage()[0].getCode()); console.log('描述:' + response.getTransactionResponse().getMessages().getMessage()[0].getDescription()); } 别的 { console.log('交易失败'); if(response.getTransactionResponse().getErrors() != null){ console.log('错误代码:' + response.getTransactionResponse().getErrors().getError()[0].getErrorCode()); console.log('错误信息:' + response.getTransactionResponse().getErrors().getError()[0].getErrorText()); } } } 别的 { console.log('交易失败。'); if(response.getTransactionResponse() != null && response.getTransactionResponse().getErrors() != null){ console.log('错误代码:' + response.getTransactionResponse().getErrors().getError()[0].getErrorCode()); console.log('错误信息:' + response.getTransactionResponse().getErrors().getError()[0].getErrorText()); } 别的 { console.log('错误代码:' + response.getMessages().getMessage()[0].getCode()); console.log('错误信息:' + response.getMessages().getMessage()[0].getText()); } } } 别的 { console.log('空响应。'); } 回调(响应); }); } if (require.main === 模块) { 收费信用卡(函数(){ console.log('chargeCreditCard 通话完成。'); }); } module.exports.chargeCreditCard = ChargeCreditCard;购物车.ts
让总计 = item.price * item.quantity;
item.options.forEach(option => (total += option.value * item.quantity));
返回总计;
}
获取总金额(){
让总计 = 0;
this.cart.forEach(item => (total += this.getItemTotal(item)));
返回总计;
}```
[1]:https://i.stack.imgur.com/ibUDr.png
【问题讨论】:
-
Stripe 提供 stripe.js 作为客户端库。它在您的应用程序中使用安全 iframe,并确保支付卡机密(号码、到期时间、cvc)永远不会接触您的服务器并且无法从您的客户端 javascript 访问。而且,它有一个甜美的用户界面。那就是你想要的。 Authorize.net 有 accept.js 做同样的事情。
-
这很有帮助。
-
知道如何改变它以使用accept.js吗?
-
我有一个与 Accet.Js Ollie 合作的 stackblitz。如果你能帮忙,你能告诉我吗? stackblitz.com/edit/angular-ivy-7tneqi?file=src%2Fapp%2Fhero.ts
标签: node.js angular deployment payment-gateway middleware