public void AddUpdateStatusJob(PushpayWebhook webhook) { // add incoming timestamp so that we can reprocess job for a // certain amount of time webhook.IncomingTimeUtc = DateTime.UtcNow; AddUpdateDonationStatusFromPushpayJob(webhook); }
public IActionResult PaymentCreated([FromBody] PushpayWebhook pushpayWebhook) { try { _pushpayService.AddUpdateStatusJob(pushpayWebhook); return(Ok()); } catch (Exception ex) { return(StatusCode(400, ex)); } }
public DonationDto UpdateDonationStatusFromPushpay(PushpayWebhook webhook, bool retry = false) { try { var pushpayPayment = _pushpayClient.GetPayment(webhook); // PushPay creates the donation a variable amount of time after the webhook comes in // so it still may not be available var donation = _donationService.GetDonationByTransactionCode(pushpayPayment.TransactionId); if (pushpayPayment.IsStatusNew || pushpayPayment.IsStatusProcessing) { donation.DonationStatusId = _mpDonationStatusPending; } else if (pushpayPayment.IsStatusSuccess) { donation.DonationStatusId = _mpDonationStatusSucceeded; } else if (pushpayPayment.IsStatusFailed) { donation.DonationStatusId = _mpDonationStatusDeclined; } _donationService.Update(donation); return(donation); } catch (Exception e) { // donation not created by pushpay yet var now = DateTime.UtcNow; var webhookTime = webhook.IncomingTimeUtc; // if it's been less than ten minutes, try again in a minute if ((now - webhookTime).TotalMinutes < maxRetryMinutes && retry) { AddUpdateDonationStatusFromPushpayJob(webhook); // dont throw an exception as Hangfire tries to handle it _logger.Error($"Payment: {webhook.Events[0].Links.Payment} not found in MP. Trying again in a minute.", e); return(null); } // it's been more than 10 minutes, let's chalk it up as PushPay // ain't going to create it and call it a day else { // dont throw an exception as Hangfire tries to handle it _logger.Error($"Payment: {webhook.Events[0].Links.Payment} not found in MP after 10 minutes of trying. Giving up.", e); return(null); } } }
public PushpayPaymentDto GetPayment(PushpayWebhook webhook) { _restClient.BaseUrl = new Uri(webhook.Events[0].Links.Payment); var token = _pushpayTokenService.GetOAuthToken(donationsScope).Wait().AccessToken; var request = new RestRequest(Method.GET); request.AddParameter("Authorization", string.Format("Bearer " + token), ParameterType.HttpHeader); var response = _restClient.Execute <PushpayPaymentDto>(request); var paymentDto = response.Data; // determine if we need to call again (multiple pages), then // determine the delay needed to avoid hitting the rate limits for Pushpay if (paymentDto == null) { throw new Exception($"Get Payment from Pushpay not successful: {response.Content}"); } return(paymentDto); }
private void AddUpdateDonationStatusFromPushpayJob(PushpayWebhook webhook) { BackgroundJob.Schedule(() => UpdateDonationStatusFromPushpay(webhook, true), TimeSpan.FromMinutes(webhookDelayMinutes)); }
private PaymentDto GetPayment(PushpayWebhook webhook) { var result = _pushpayClient.GetPayment(webhook); return(_mapper.Map <PaymentDto>(result)); }