Exemplo n.º 1
0
        public async Task <ActionResult> Webhook([FromBody] MobilePayWebhook request, [FromHeader(Name = "x-mobilepay-signature")] string mpSignatureHeader)
        {
            var isSignatureValid = await VerifySignature(mpSignatureHeader);

            if (!isSignatureValid)
            {
                Log.Error("Signature did not match the computed signature. Request Body: {Request} Signature: {Signature}", request, mpSignatureHeader);
                return(BadRequest("Signature is not valid"));
            }

            Log.Information("MobilePay Webhook invoked. Request: {Request}", request);
            await _purchaseService.HandleMobilePayPaymentUpdate(request);

            return(NoContent());
        }
Exemplo n.º 2
0
        public async Task HandleMobilePayPaymentUpdate(MobilePayWebhook webhook)
        {
            var purchase = await _context.Purchases
                .Include(p => p.PurchasedBy)
                .Where(p => p.TransactionId.Equals(webhook.Data.Id))
                .FirstOrDefaultAsync();
            if (purchase == null)
            {
                Log.Error("No purchase was found by TransactionId: {Id} from Webhook request", webhook.Data.Id);
                throw new EntityNotFoundException($"No purchase was found by Transaction Id: {webhook.Data.Id} from webhook request");
            }

            if (purchase.Completed || purchase.Completed)
            {
                // FIXME Check purchase is not already completed. Should we throw an error? Conflict?
                Log.Warning("Purchase from Webhook request is already completed. Purchase Id: {PurchaseId}, Transaction Id: {TransactionId}", purchase.Id, webhook.Data.Id);
                return;
            }

            var eventTypeLowerCase = webhook.EventType.ToLower();
            switch (eventTypeLowerCase)
            {
                case "payment.reserved":
                {
                    await CompletePurchase(purchase);
                    break;
                }
                case "payment.cancelled_by_user":
                {
                    await CancelPurchase(purchase);
                    break;
                }
                case "payment.expired":
                {
                    await CancelPurchase(purchase);
                    break;
                }
                default:
                    Log.Error("Unknown EventType from Webhook request. Event Type: {EventType}, Purchase Id: {PurchaseId}, Transaction Id: {TransactionId}", eventTypeLowerCase, purchase.Id, webhook.Data.Id);
                    throw new ArgumentException($"Event Type {eventTypeLowerCase} is not valid");
            }
        }