Skip to content
Snippets Groups Projects

Update StripePaymentintent.Process API

Merged mattwire requested to merge StripePaymentintent into master
2 files
+ 95
26
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -109,21 +109,38 @@ function _civicrm_api3_stripe_paymentintent_process_spec(&$spec) {
* @throws \Stripe\Exception\UnknownApiErrorException
*/
function civicrm_api3_stripe_paymentintent_process($params) {
$paymentMethodID = $params['payment_method_id'];
$paymentIntentID = $params['payment_intent_id'];
$amount = $params['amount'];
$capture = $params['capture'];
$title = $params['description'];
$confirm = TRUE;
if (empty($amount)) {
$amount = 1;
$confirm = FALSE;
if (class_exists('\Civi\Firewall\Firewall')) {
if (!\Civi\Firewall\Firewall::isCSRFTokenValid(CRM_Utils_Type::validate($params['csrfToken'], 'String'))) {
_civicrm_api3_stripe_paymentintent_returnInvalid();
}
}
$paymentMethodID = CRM_Utils_Type::validate($params['payment_method_id'], 'String');
$paymentIntentID = CRM_Utils_Type::validate($params['payment_intent_id'], 'String');
$capture = CRM_Utils_Type::validate($params['capture'], 'Boolean', FALSE);
$amount = CRM_Utils_Type::validate($params['amount'], 'String');
// $capture is normally true if we have already created the intent and just need to get extra
// authentication from the user (eg. on the confirmation page). So we don't need the amount
// in this case.
if (empty($amount) && !$capture) {
_civicrm_api3_stripe_paymentintent_returnInvalid();
}
$currency = $params['currency'];
$processorID = $params['payment_processor_id'];
$processor = new CRM_Core_Payment_Stripe('', civicrm_api3('PaymentProcessor', 'getsingle', ['id' => $processorID]));
$title = CRM_Utils_Type::validate($params['description'], 'String');
$intentParams['confirm'] = TRUE;
$currency = CRM_Utils_Type::validate($params['currency'], 'String', CRM_Core_Config::singleton()->defaultCurrency);
$processorID = CRM_Utils_Type::validate((int)$params['id'], 'Positive');
!empty($processorID) ?: _civicrm_api3_stripe_paymentintent_returnInvalid();
$paymentProcessor = civicrm_api3('PaymentProcessor', 'getsingle', ['id' => $processorID]);
($paymentProcessor['class_name'] === 'Payment_Stripe') ?: _civicrm_api3_stripe_paymentintent_returnInvalid();
$processor = new CRM_Core_Payment_Stripe('', $paymentProcessor);
$processor->setAPIParams();
$intentParams['confirmation_method'] = 'manual';
if (empty($paymentIntentID) && empty($paymentMethodID)) {
$intentParams['confirm'] = FALSE;
$intentParams['confirmation_method'] = 'automatic';
}
if ($paymentIntentID) {
// We already have a PaymentIntent, retrieve and attempt confirm.
$intent = \Stripe\PaymentIntent::retrieve($paymentIntentID);
@@ -137,28 +154,53 @@ function civicrm_api3_stripe_paymentintent_process($params) {
else {
// We don't yet have a PaymentIntent, create one using the
// Payment Method ID and attempt to confirm it too.
$intent = \Stripe\PaymentIntent::create([
'payment_method' => $paymentMethodID,
'amount' => $processor->getAmount(['amount' => $amount, 'currency' => $currency]),
'currency' => $currency,
'confirmation_method' => 'manual',
'capture_method' => 'manual',
try {
$intentParams['amount'] = $processor->getAmount(['amount' => $amount, 'currency' => $currency]);
$intentParams['currency'] = $currency;
// authorize the amount but don't take from card yet
'setup_future_usage' => 'off_session',
$intentParams['capture_method'] = 'manual';
// Setup the card to be saved and used later
'confirm' => $confirm,
]);
$intentParams['setup_future_usage'] = 'off_session';
if ($paymentMethodID) {
$intentParams['payment_method'] = $paymentMethodID;
}
$intent = $processor->stripeClient->paymentIntents->create($intentParams);
} catch (Exception $e) {
// Save the "error" in the paymentIntent table in in case investigation is required.
$stripePaymentintentParams = [
'paymentintent_id' => 'null',
'payment_processor_id' => $processorID,
'status' => 'failed',
'description' => "{$e->getRequestId()};{$e->getMessage()};{$title}",
'referrer' => $_SERVER['HTTP_REFERER'],
];
CRM_Stripe_BAO_StripePaymentintent::create($stripePaymentintentParams);
if ($e instanceof \Stripe\Exception\CardException) {
if (($e->getDeclineCode() === 'fraudulent') && class_exists('\Civi\Firewall\Event\FraudEvent')) {
\Civi\Firewall\Event\FraudEvent::trigger(\CRM_Utils_System::ipAddress(), 'CRM_Stripe_AJAX::confirmPayment');
}
$message = $e->getMessage();
}
elseif ($e instanceof \Stripe\Exception\InvalidRequestException) {
$message = 'Invalid request';
}
return civicrm_api3_create_error(['message' => $message]);
}
}
// Save the generated paymentIntent in the CiviCRM database for later tracking
$intentParams = [
$stripePaymentintentParams = [
'paymentintent_id' => $intent->id,
'payment_processor_id' => $processorID,
'status' => $intent->status,
'description' => $title,
'description' => "{$title}",
'referrer' => $_SERVER['HTTP_REFERER'],
];
CRM_Stripe_BAO_StripePaymentintent::create($intentParams);
CRM_Stripe_BAO_StripePaymentintent::create($stripePaymentintentParams);
// generatePaymentResponse()
if ($intent->status === 'requires_action' &&
$intent->next_action->type === 'use_stripe_sdk') {
// Tell the client to handle the action
@@ -182,8 +224,28 @@ function civicrm_api3_stripe_paymentintent_process($params) {
'paymentIntent' => ['id' => $intent->id],
]);
}
elseif ($intent->status === 'requires_payment_method') {
return civicrm_api3_create_success([
'requires_payment_method' => true,
'payment_intent_client_secret' => $intent->client_secret,
]);
}
else {
// Invalid status
throw new API_Exception('Invalid PaymentIntent status');
if (isset($intent->last_payment_error->message)) {
$message = E::ts('Payment failed: %1', [1 => $intent->last_payment_error->message]);
}
else {
$message = E::ts('Payment failed.');
}
return civicrm_api3_create_error($message);
}
}
/**
* Passed parameters were invalid
*/
function _civicrm_api3_stripe_paymentintent_returnInvalid() {
http_response_code(400);
exit(1);
}
Loading