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

Remove old IPN code

parent c98ea2b4
No related branches found
No related tags found
1 merge request!217Implement Stripe Checkout (with support for SEPA and ACH)
...@@ -475,234 +475,4 @@ class CRM_Core_Payment_StripeIPN { ...@@ -475,234 +475,4 @@ class CRM_Core_Payment_StripeIPN {
return $return; return $return;
} }
/**
* Create the next contribution for a recurring contribution
* This happens when Stripe generates a new invoice and notifies us (normally by invoice.finalized but
* invoice.payment_succeeded sometimes arrives first).
*
* @throws \CiviCRM_API3_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function createNextContributionForRecur() {
// We have a recurring contribution but no contribution so we'll repeattransaction
// Stripe has generated a new invoice (next payment in a subscription) so we
// create a new contribution in CiviCRM
$params = [
'contribution_recur_id' => $this->contribution_recur_id,
'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending'),
'receive_date' => $this->receive_date,
'order_reference' => $this->invoice_id,
'trxn_id' => $this->charge_id,
'total_amount' => $this->amount,
'fee_amount' => $this->fee,
];
$this->repeatContribution($params);
// Don't touch the contributionRecur as it's updated automatically by Contribution.repeattransaction
}
/**
* Gather and set info as class properties.
*
* Given the data passed to us via the Stripe Event, try to determine
* as much as we can about this event and set that information as
* properties to be used later.
*
* @return bool TRUE if we were able to find a contribution (via getContribution)
* @throws \CRM_Core_Exception
*/
public function setInfo() {
if (!$this->getCustomer()) {
if ((bool)\Civi::settings()->get('stripe_ipndebug')) {
$message = $this->getPaymentProcessor()->getPaymentProcessorLabel() . ': ' . $this->getEventID() . ': Missing customer_id';
Civi::log()->debug($message);
}
// return FALSE;
}
$this->receive_date = $this->retrieve('receive_date', 'String', FALSE);
$this->amount = $this->retrieve('amount', 'String', FALSE);
if (($this->getData()->object->object !== 'charge') && (!empty($this->charge_id))) {
$charge = $this->getPaymentProcessor()->stripeClient->charges->retrieve($this->charge_id);
$balanceTransactionID = CRM_Stripe_Api::getObjectParam('balance_transaction', $charge);
}
else {
$balanceTransactionID = CRM_Stripe_Api::getObjectParam('balance_transaction', $this->getData()->object);
}
try {
$balanceTransaction = $this->getPaymentProcessor()->stripeClient->balanceTransactions->retrieve($balanceTransactionID);
$this->fee = $this->getPaymentProcessor()->getFeeFromBalanceTransaction($balanceTransaction, $this->retrieve('currency', 'String', FALSE));
}
catch (Exception $e) {
throw new \Civi\Payment\Exception\PaymentProcessorException("Error retrieving balanceTransaction {$balanceTransactionID}. " . $e->getMessage());
}
// Get the CiviCRM recurring contribution that matches the Stripe subscription (if we have one).
$this->getSubscriptionDetails();
// Get the CiviCRM contribution that matches the Stripe metadata we have from the event
return $this->getContribution();
}
/**
* Get the recurring contribution from the Stripe event parameters (subscription_id)
* and set subscription_id, contribution_recur_id vars.
*
* @return bool
* @throws \CRM_Core_Exception
*/
public function getSubscriptionDetails() {
if (!$this->subscription_id) {
return FALSE;
}
// Get the recurring contribution record associated with the Stripe subscription.
$contributionRecur = ContributionRecur::get(FALSE)
->addWhere('processor_id', '=', $this->subscription_id)
->addWhere('is_test', 'IN', [TRUE, FALSE])
->execute()
->first();
if (empty($contributionRecur)) {
if ((bool)\Civi::settings()->get('stripe_ipndebug')) {
$message = $this->getPaymentProcessor()->getPaymentProcessorLabel() . ': ' . $this->getEventID() . ': Cannot find recurring contribution for subscription ID: ' . $this->subscription_id;
Civi::log()->debug($message);
}
return FALSE;
}
$this->contribution_recur_id = $contributionRecur['id'];
$this->contributionRecur = $contributionRecur;
return TRUE;
}
/**
* A) A one-off contribution will have trxn_id == stripe.charge_id
* B) A contribution linked to a recur (stripe subscription):
* 1. May have the trxn_id == stripe.subscription_id if the invoice was not generated at the time the contribution
* was created
* (Eg. the recur was setup with a future recurring start date).
* This will be updated to trxn_id == stripe.invoice_id when a suitable IPN is received
* @todo: Which IPN events will update this?
* 2. May have the trxn_id == stripe.invoice_id if the invoice was generated at the time the contribution was
* created OR the contribution has been updated by the IPN when the invoice was generated.
*
* @return bool
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
private function getContribution() {
$paymentParams = [
'contribution_test' => $this->getPaymentProcessor()->getIsTestMode(),
];
// A) One-off contribution
if (!empty($this->charge_id)) {
$paymentParams['trxn_id'] = $this->charge_id;
$contribution = civicrm_api3('Mjwpayment', 'get_contribution', $paymentParams);
}
// B2) Contribution linked to subscription and we have invoice_id
// @todo there is a case where $contribution is not defined (i.e. if charge_id is empty)
if (!$contribution['count']) {
unset($paymentParams['trxn_id']);
if (!empty($this->invoice_id)) {
$paymentParams['order_reference'] = $this->invoice_id;
$contribution = civicrm_api3('Mjwpayment', 'get_contribution', $paymentParams);
}
}
// B1) Contribution linked to subscription and we have subscription_id
// @todo there is a case where $contribution is not defined (i.e. if charge_id, invoice_id are empty)
if (!$contribution['count']) {
unset($paymentParams['trxn_id']);
if (!empty($this->subscription_id)) {
$paymentParams['order_reference'] = $this->subscription_id;
$contribution = civicrm_api3('Mjwpayment', 'get_contribution', $paymentParams);
}
}
// @todo there is a case where $contribution is not defined (i.e. if charge_id, invoice_id, subscription_id are empty)
if (!$contribution['count']) {
if ((bool)\Civi::settings()->get('stripe_ipndebug')) {
$message = $this->getPaymentProcessor()->getPaymentProcessorLabel() . 'No matching contributions for event ' . $this->getEventID();
Civi::log()->debug($message);
}
$result = [];
CRM_Mjwshared_Hook::webhookEventNotMatched('stripe', $this, 'contribution_not_found', $result);
if (empty($result['contribution'])) {
return FALSE;
}
$this->contribution = $result['contribution'];
}
else {
$this->contribution = $contribution['values'][$contribution['id']];
}
return TRUE;
}
/**
* Get the Stripe customer details and match to the StripeCustomer record in CiviCRM
* This gives us $this->contactID
*
* @return bool
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
private function getCustomer() {
$this->customer_id = CRM_Stripe_Api::getObjectParam('customer_id', $this->getData()->object);
if (empty($this->customer_id)) {
$this->exception('Missing customer_id!');
}
try {
$customer = civicrm_api3('StripeCustomer', 'getsingle', [
'customer_id' => $this->customer_id,
]);
$this->contactID = $customer['contact_id'];
if ($this->getPaymentProcessor()->getID() !== (int) $customer['processor_id']) {
$this->exception("Customer ({$this->customer_id}) and payment processor ID don't match (expected: {$customer['processor_id']}, actual: {$this->getPaymentProcessor()->getID()})");
}
}
catch (Exception $e) {
// Customer not found in CiviCRM
if ((bool)\Civi::settings()->get('stripe_ipndebug') && !$this->contribution) {
$message = $this->getPaymentProcessor()->getPaymentProcessorLabel() . 'Stripe Customer not found in CiviCRM for event ' . $this->getEventID();
Civi::log()->debug($message);
}
CRM_Mjwshared_Hook::webhookEventNotMatched('stripe', $this, 'customer_not_found');
return FALSE;
}
return TRUE;
}
/**
* This allows us to end a subscription once:
* a) We've reached the end date / number of installments
* b) The recurring contribution is marked as completed
*
* @throws \CiviCRM_API3_Exception
*/
private function handleInstallmentsForSubscription() {
if ((!$this->contribution_recur_id) || (!$this->subscription_id)) {
return;
}
$contributionRecur = civicrm_api3('ContributionRecur', 'getsingle', [
'id' => $this->contribution_recur_id,
]);
if (empty($contributionRecur['end_date'])) {
return;
}
// There is no easy way of retrieving a count of all invoices for a subscription so we ignore the "installments"
// parameter for now and rely on checking end_date (which was calculated based on number of installments...)
// if (empty($contributionRecur['installments'])) { return; }
$stripeSubscription = $this->getPaymentProcessor()->stripeClient->subscriptions->retrieve($this->subscription_id);
// If we've passed the end date cancel the subscription
if (($stripeSubscription->current_period_end >= strtotime($contributionRecur['end_date']))
|| ($contributionRecur['contribution_status_id']
== CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_ContributionRecur', 'contribution_status_id', 'Completed'))) {
$this->getPaymentProcessor()->stripeClient->subscriptions->update($this->subscription_id, ['cancel_at_period_end' => TRUE]);
$this->updateRecurCompleted(['id' => $this->contribution_recur_id]);
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment