Skip to content
Open
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Threading.Tasks;
using CyberSource.Model;
using VirtoCommerce.CyberSourcePayment.Core.Models;
using VirtoCommerce.OrdersModule.Core.Model;

namespace VirtoCommerce.CyberSourcePayment.Core.Services;

Expand All @@ -11,4 +12,5 @@ public interface ICyberSourceClient
Task<PtsV2PaymentsCapturesPost201Response> CapturePayment(CyberSourceCapturePaymentRequest request);
Task<PtsV2PaymentsRefundPost201Response> RefundPayment(CyberSourceRefundPaymentRequest request);
Task<PtsV2PaymentsVoidsPost201Response> VoidPayment(CyberSourceVoidPaymentRequest request);
Task<PaymentIn> RefreshPaymentStatus(PaymentIn payment);
}
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ or CyberSourceRequest.PaymentStatus.AuthorizedRiskDeclined

CyberSourceRequest.PaymentStatus.InvalidRequest => PaymentInvalid(response, payment),

// note: see the CyberSourceClient.RefreshPaymentStatus method too
CyberSourceRequest.PaymentStatus.PendingAuthentication
or CyberSourceRequest.PaymentStatus.PartialAuthorized
or CyberSourceRequest.PaymentStatus.AuthorizedPendingReview
Expand Down Expand Up @@ -360,9 +361,11 @@ PaymentIn payment
payment.ProcessPaymentResult = new ProcessPaymentRequestResult { ErrorMessage = errorMessage };
payment.Comment = $"{errorMessage}{Environment.NewLine}";
payment.OuterId = response.Id;
payment.Status = PaymentStatus.Pending.ToString();

return new PostProcessPaymentRequestResult
{
NewPaymentStatus = PaymentStatus.Pending,
ErrorMessage = errorMessage,
IsSuccess = true,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,24 @@
using Polly;
using VirtoCommerce.CustomerModule.Core.Model;
using VirtoCommerce.CustomerModule.Core.Services;
using VirtoCommerce.CyberSourcePayment.Core;
using VirtoCommerce.CyberSourcePayment.Core.Models;
using VirtoCommerce.CyberSourcePayment.Core.Services;
using VirtoCommerce.OrdersModule.Core.Model;
using VirtoCommerce.OrdersModule.Core.Services;
using VirtoCommerce.PaymentModule.Core.Model;
using VirtoCommerce.Platform.Core.Security;
using VirtoCommerce.Platform.Core.Settings;
using VirtoCommerce.StoreModule.Core.Services;

namespace VirtoCommerce.CyberSourcePayment.Data.Services;

public class CyberSourceClient(
IOptions<CyberSourcePaymentMethodOptions> options,
IMemberService memberService,
ICustomerOrderService orderService,
IStoreService storeService,
ISettingsManager settingsManager,
Func<UserManager<ApplicationUser>> userManagerFactory,
CyberSourceJwkValidator jwkValidator
) : ICyberSourceClient
Expand All @@ -47,7 +55,6 @@ protected virtual async Task<JwtKeyModel> GenerateCaptureContextInternal(CyberSo
[context.StoreUrl],
context.CardTypes.ToList()
);

var config = CreateConfiguration(context.Sandbox);
var api = new MicroformIntegrationApi(config);
var jwt = await api.GenerateCaptureContextAsync(request);
Expand Down Expand Up @@ -230,10 +237,45 @@ protected virtual async Task<Ptsv2paymentsOrderInformation> GetOrderInfo(Payment
Currency = order.Currency,
},
};

return result;
}

public async Task<PaymentIn> RefreshPaymentStatus(PaymentIn payment)
{
if (payment.Status == PaymentStatus.Pending.ToString())
{
var order = (await orderService.GetAsync([payment.OrderId])).First();
var store = (await storeService.GetAsync([order.StoreId])).First();

await settingsManager.DeepLoadSettingsAsync(store);
var sandbox = store.Settings.GetValue<bool>(ModuleConstants.Settings.General.Sandbox);
var config = CreateCyberSourceClientConfig(sandbox);

var api = new TransactionDetailsApi(config);
var result = await api.GetTransactionAsync(payment.OuterId);

// if (result.Status != CyberSourceRequest.PaymentStatus.Pending)
// result.ApplicationInformation.ReasonCode >= 480
if (result.Status != null)
{
var paymentToSave = order.InPayments.First(x => x.Id == payment.Id);
paymentToSave.Status = result.Status;
await orderService.SaveChangesAsync([order]);
return paymentToSave;
}
}

return payment;
}

protected virtual Configuration CreateCyberSourceClientConfig(bool sandbox)
{
return new Configuration
{
MerchantConfigDictionaryObj = options.Value.ToDictionary(sandbox), // todo: SANDBOX
};
}

protected virtual async Task<Ptsv2paymentsidcapturesOrderInformation> GetCaptureOrderInfo(CyberSourceCapturePaymentRequest request)
{
using var userManager = userManagerFactory();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using VirtoCommerce.CyberSourcePayment.Core.Services;
using VirtoCommerce.OrdersModule.Core.Services;

namespace VirtoCommerce.CyberSourcePayment.Web.Controllers.Api;

[Authorize]
[Route("api/payments/cybersource")]
public class PaymentsController(
ICyberSourceClient client,
IPaymentService paymentService
) : Controller
{
[HttpPost]
[Route("refresh-payment-status/{paymentId}")]
public virtual async Task<IActionResult> RefreshPaymentStatus(string paymentId)
{
var payment = (await paymentService.GetAsync([paymentId])).First();
var result = await client.RefreshPaymentStatus(payment);
return Ok(result);
}
}
Loading