Skip to content
Snippets Groups Projects
Commit 26256969 authored by mattwire's avatar mattwire
Browse files

Fix charge.failed for StripeCheckout and add test

parent 78b4a5d1
No related branches found
No related tags found
1 merge request!217Implement Stripe Checkout (with support for SEPA and ACH)
......@@ -481,10 +481,11 @@ class Events {
return $return;
}
$paymentIntentID = $this->getValueFromStripeObject('payment_intent_id', 'String');
// Invoice ID is optional
$invoiceID = $this->getValueFromStripeObject('invoice_id', 'String');
$contribution = $this->findContribution($chargeID, $invoiceID);
$contribution = $this->findContribution($chargeID, $invoiceID, '', $paymentIntentID);
if (empty($contribution)) {
$return->message = __FUNCTION__ . ' Contribution not found';
return $return;
......@@ -492,10 +493,11 @@ class Events {
$failedContributionParams = [
'contribution_id' => $contribution['id'],
'order_reference' => $invoiceID ?? $chargeID,
'cancel_date' => $this->getValueFromStripeObject('receive_date', 'String'),
'cancel_reason' => $this->getValueFromStripeObject('failure_message', 'String'),
];
// Fallback from invoiceID to chargeID. We can't use ?? because invoiceID might be empty string ie. '' and not NULL
$failedContributionParams['order_reference'] = empty($invoiceID) ? $chargeID : $invoiceID;
$this->updateContributionFailed($failedContributionParams);
$return->message = __FUNCTION__ . ' contributionID: ' . $contribution['id'];
......
......@@ -373,6 +373,88 @@ class CRM_Stripe_IpnTest extends CRM_Stripe_BaseTest {
]);
}
/**
* Unlike charge succeeded, charge failed is processed.
*/
public function testNewOneOffStripeCheckoutChargeFailed() {
$this->setOrCreateStripeCheckoutPaymentProcessor();
$this->getMocksForOneOffPayment();
$contribution = $this->setupPendingContribution(['invoice_id' => md5(uniqid(mt_rand(), TRUE))]);
// Simulate payment
$this->assertInstanceOf('CRM_Core_Payment_StripeCheckout', $this->paymentObject);
//
// Check the Contribution
// ...should be pending
// ...its transaction ID should be our Charge ID.
//
$this->checkContrib([
'contribution_status_id' => 'Pending',
'trxn_id' => '',
'invoice_id' => $contribution['invoice_id']
]);
// Set the new contribution to have trxn_id=pi_mock
$success = $this->simulateEvent([
'type' => 'checkout.session.completed',
'id' => 'evt_mock',
'object' => 'event', // ?
'livemode' => FALSE,
'pending_webhooks' => 0,
'request' => [ 'id' => NULL ],
'data' => [
'object' => [
'id' => 'cs_mock',
'object' => 'checkout.session',
'customer' => 'cus_mock',
'payment_intent' => 'pi_mock',
'client_reference_id' => $contribution['invoice_id'],
]
],
]);
$this->assertEquals(TRUE, $success, 'IPN did not return OK');
$this->checkContrib([
'contribution_status_id' => 'Pending',
'trxn_id' => 'pi_mock',
]);
$success = $this->simulateEvent([
'type' => 'charge.failed',
'id' => 'evt_mock',
'object' => 'event',
'livemode' => FALSE,
'pending_webhooks' => 0,
'request' => [ 'id' => NULL ],
'data' => [
'object' => [
'id' => 'ch_mock',
'object' => 'charge',
'amount' => $this->total*100,
'amount_captured' => $this->total*100,
'captured' => TRUE,
'balance_transaction' => 'txn_mock',
'customer' => 'cus_mock',
'payment_intent' => 'pi_mock',
'created' => time(),
'failure_message' => 'Mocked failure',
]
],
]);
$this->assertEquals(TRUE, $success, 'IPN did not return OK');
//
// Ensure Contribution is marked Failed, with the reason, and that the
// ContributionRecur is not changed from Pending.
//
$this->checkContrib([
'contribution_status_id' => 'Failed',
'trxn_id' => 'ch_mock',
'cancel_reason' => 'Mocked failure',
]);
}
/**
* Test creating a recurring contribution and
* update it after creation. @todo The membership should also be updated.
......@@ -487,11 +569,11 @@ class CRM_Stripe_IpnTest extends CRM_Stripe_BaseTest {
]);
$this->checkContribRecur([ 'contribution_status_id' => 'Pending' ]);
}
/**
* Unlike charge succeeded, charge failed is processed.
*/
public function testNewRecurringChargeFailed() {
$this->mockRecurringPaymentSetup();
$success = $this->simulateEvent([
......@@ -527,8 +609,9 @@ class CRM_Stripe_IpnTest extends CRM_Stripe_BaseTest {
'trxn_id' => 'in_mock',
'cancel_reason' => 'Mocked failure',
]);
$this->checkContribRecur([ 'contribution_status_id' => 'Pending' ]);
$this->checkContribRecur(['contribution_status_id' => 'Pending']);
}
/**
*
* @see https://stripe.com/docs/billing/invoices/overview#invoice-status-transition-endpoints-and-webhooks
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment