使用Sitefinity电子商务实现3D安全
本文关键字:3D 安全 实现 电子商务 Sitefinity 使用 | 更新日期: 2023-09-27 18:29:54
我想为通过网站进行的信用卡支付添加3D安全身份验证。我使用电子商务插件Sitefinity 8和SagePay作为支付处理器。
我已经创建了一个自定义支付提供商,可以成功地将用户重定向到3D安全页面。我可以使用SagePay集成工具包(即从电子商务插件外部)对SagePay进行第二次身份验证调用。然而,由于内部电子商务课程的运作方式,我正在努力寻找完成付款的方法。
困难在于,如果需要3D安全身份验证,订单处理器会将付款视为拒绝,但似乎没有一种方法可以在不使用内置功能的情况下正确处理订单。从我对电子商务库的检查来看,由于internal
修饰符和具体实现,似乎没有办法扩展或修改这些类。
完成验证后,如何处理订单?有人成功地通过电子商务实现了3D安全吗?或者知道这是否可能?
这是我目前的自定义支付提供商。
public class CustomSagePayProvider : SagePayProvider
{
// Rest of code...
protected override IPaymentResponse ParseReponse(string uniqueTransactionCode, string responseXml)
{
var paymentResponse = base.ParseReponse(uniqueTransactionCode, responseXml);
if (Requires3DSecure(paymentResponse))
{
var responseFields = GetResponseAsDictionary(responseXml);
Set3DSecureFields(responseFields, paymentResponse);
}
return paymentResponse;
}
private bool Requires3DSecure(IPaymentResponse paymentResponse)
{
return paymentResponse.GatewayCSCResponse == "OK";
}
private void Set3DSecureFields(Dictionary<string, string> responseFields, IPaymentResponse paymentResponse)
{
var postValues = new NameValueCollection();
postValues.Add("MD", responseFields.ContainsKey("MD") ? responseFields["MD"] : string.Empty);
postValues.Add("PAReq", responseFields.ContainsKey("PAReq") ? responseFields["PAReq"] : string.Empty);
paymentResponse.GatewayRedirectUrlPostValues = postValues;
paymentResponse.GatewayRedirectUrl = responseFields.ContainsKey("ACSURL") ? responseFields["ACSURL"] : string.Empty;
}
}
这是使用.NET SagePay集成套件的3D安全支付过程
using SagePay.IntegrationKit;
using SagePay.IntegrationKit.Messages;
// Rest of code
var sagePay = new SagePayIntegration();
IThreeDAuthRequest request = new DataObject();
request.Md = Request.Form["MD"];
request.PaRes = Request.Form["PaRes"];
sagePay.RequestQueryString = sagePay.BuildQueryString(request, ProtocolMessage.THREE_D_AUTH_REQUEST, ProtocolVersion.V_223);
sagePay.ResponseQueryString = sagePay.ProcessWebRequestToSagePay("https://test.sagepay.com/gateway/service/direct3dcallback.vsp", sagePay.RequestQueryString);
var result = sagePay.GetDirectPaymentResult(sagePay.ResponseQueryString);
if (result.Status == ResponseStatus.OK)
{
// Process order
}
我能够通过将第二次身份验证呼叫视为异地支付并将IOffsitePaymentProcessorProvider
接口添加到我的支付提供商类来添加3D安全身份验证
public class CustomSagePayProvider : SagePayProvider, IOffsitePaymentProcessorProvider
{
// Triggered after payments that have been 3D Secure authenticated
public IPaymentResponse HandleOffsiteNotification(int orderNumber, HttpRequest request, PaymentMethod paymentMethod)
{
var paymentResponse = new PaymentResponse() { IsOffsitePayment = true };
var sagePay = new SagePayIntegration();
var result = sagePay.GetDirectPaymentResult(request.Params.ToString());
if (result.ThreeDSecureStatus == ThreeDSecureStatus.OK)
{
paymentResponse.IsSuccess = true;
paymentResponse.GatewayTransactionID = result.TxAuthNo.ToString();
}
return paymentResponse;
}
public IPaymentResponse HandleOffsiteReturn(int orderNumber, HttpRequest request, PaymentMethod paymentMethod)
{
throw new NotImplementedException();
}
在第一次请求身份验证时,我将通知url作为termUrl
值中的查询字符串参数传递给SagePay(url必须是/Ecommerce/offsite-payment-notification/
才能使用内置的越位支付通知处理程序)。
var notificationUrl = request.Url.GetLeftPart(UriPartial.Authority) + "/Ecommerce/offsite-payment-notification/";
在用户完成身份验证后,在SagePay的回调中,我使用SagePay集成工具包来处理身份验证的结果。
var sagePay = new SagePayIntegration();
IThreeDAuthRequest request = new DataObject();
request.Md = md;
request.PaRes = paRes;
sagePay.RequestQueryString = sagePay.BuildQueryString(request, ProtocolMessage.THREE_D_AUTH_REQUEST, ProtocolVersion.V_223);
sagePay.ResponseQueryString = sagePay.ProcessWebRequestToSagePay("https://test.sagepay.com/gateway/service/direct3dcallback.vsp", sagePay.RequestQueryString);
return sagePay.GetDirectPaymentResult(sagePay.ResponseQueryString);
最后,我通过发布到url www.mysite.com/Ecommerce/offsite-payment-notification/
来触发HandleOffsiteNotification
事件。这会将订单标记为已完成,更新库存水平并清理用户的购物篮。为了简单起见,在本例中,我使用SagePay集成工具包对象来构建查询字符串并发布到url。
var sagePay = new SagePayIntegration();
var ordersManager = OrdersManager.GetManager();
var query = sagePay.ConvertSagePayMessageToNameValueCollection(ProtocolMessage.DIRECT_PAYMENT_RESULT, typeof(IDirectPaymentResult), result, ProtocolVersion.V_223);
// Required Sitefinity fields to trigger HandleOffsiteNotification in IOffsitePaymentProcessorProvider
query.Add("invoice", orderNumber.ToString());
query.Add("provider", ordersManager.Provider.Name);
var queryString = sagePay.BuildQueryString(query);
// Post 3d secure details to this site simulate an offsite payment processor response
sagePay.ProcessWebRequestToSagePay(notificationUrl, queryString);