...
 
Commits (7)
......@@ -151,102 +151,7 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN {
* @throws \CRM_Core_Exception
*/
public function retrieve($name, $type, $abort = TRUE) {
$className = get_class($this->_inputParameters->data->object);
$value = NULL;
switch ($className) {
case 'Stripe\Charge':
switch ($name) {
case 'charge_id':
$value = $this->_inputParameters->data->object->id;
break;
case 'failure_code':
$value = $this->_inputParameters->data->object->failure_code;
break;
case 'failure_message':
$value = $this->_inputParameters->data->object->failure_message;
break;
case 'refunded':
$value = $this->_inputParameters->data->object->refunded;
break;
case 'amount_refunded':
$value = $this->_inputParameters->data->object->amount_refunded;
break;
}
break;
case 'Stripe\Invoice':
switch ($name) {
case 'charge_id':
$value = $this->_inputParameters->data->object->charge;
break;
case 'invoice_id':
$value = $this->_inputParameters->data->object->id;
break;
case 'receive_date':
$value = date("Y-m-d H:i:s", $this->_inputParameters->data->object->date);
break;
case 'subscription_id':
$value = $this->_inputParameters->data->object->subscription;
break;
}
break;
case 'Stripe\Subscription':
switch ($name) {
case 'frequency_interval':
$value = $this->_inputParameters->data->object->plan->interval_count;
break;
case 'frequency_unit':
$value = $this->_inputParameters->data->object->plan->interval;
break;
case 'plan_amount':
$value = $this->_inputParameters->data->object->plan->amount / 100;
break;
case 'plan_id':
$value = $this->_inputParameters->data->object->plan->id;
break;
case 'plan_name':
$value = $this->_inputParameters->data->object->plan->name;
break;
case 'plan_start':
$value = date("Y-m-d H:i:s", $this->_inputParameters->data->object->start);
break;
case 'subscription_id':
$value = $this->_inputParameters->data->object->id;
break;
}
break;
}
// Common parameters
switch ($name) {
case 'customer_id':
$value = $this->_inputParameters->data->object->customer;
break;
case 'event_type':
$value = $this->_inputParameters->type;
break;
case 'previous_plan_id':
if (preg_match('/\.updated$/', $this->_inputParameters->type)) {
$value = $this->_inputParameters->data->previous_attributes->plan->id;
}
break;
}
$value = CRM_Stripe_Api::getObjectParam($name, $type, $this->_inputParameters->data->object);
$value = CRM_Utils_Type::validate($value, $type, FALSE);
if ($abort && $value === NULL) {
......@@ -262,7 +167,7 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN {
*/
public function main() {
// Collect and determine all data about this event.
$this->event_type = $this->retrieve('event_type', 'String');
$this->event_type = CRM_Stripe_Api::getParam('event_type', $this->_inputParameters);
$pendingStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
......@@ -454,13 +359,17 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN {
*/
public function setInfo() {
$abort = FALSE;
$this->customer_id = $this->retrieve('customer_id', 'String');
$this->customer_id = CRM_Stripe_Api::getParam('customer_id', $this->_inputParameters);
if (empty($this->customer_id)) {
$this->exception('Missing customer_id!');
}
$this->previous_plan_id = CRM_Stripe_Api::getParam('previous_plan_id', $this->_inputParameters);
$this->subscription_id = $this->retrieve('subscription_id', 'String', $abort);
$this->invoice_id = $this->retrieve('invoice_id', 'String', $abort);
$this->receive_date = $this->retrieve('receive_date', 'String', $abort);
$this->charge_id = $this->retrieve('charge_id', 'String', $abort);
$this->plan_id = $this->retrieve('plan_id', 'String', $abort);
$this->previous_plan_id = $this->retrieve('previous_plan_id', 'String', $abort);
$this->plan_amount = $this->retrieve('plan_amount', 'String', $abort);
$this->frequency_interval = $this->retrieve('frequency_interval', 'String', $abort);
$this->frequency_unit = $this->retrieve('frequency_unit', 'String', $abort);
......
<?php
class CRM_Stripe_Api {
public static function getObjectParam($name, $stripeObject) {
$className = get_class($stripeObject);
switch ($className) {
case 'Stripe\Charge':
switch ($name) {
case 'charge_id':
return (string) $stripeObject->id;
case 'failure_code':
return (string) $stripeObject->failure_code;
case 'failure_message':
return (string) $stripeObject->failure_message;
case 'refunded':
return (bool) $stripeObject->refunded;
case 'amount_refunded':
return (int) $stripeObject->amount_refunded / 100;
}
break;
case 'Stripe\Invoice':
switch ($name) {
case 'charge_id':
return (string) $stripeObject->charge;
case 'invoice_id':
return (string) $stripeObject->id;
case 'receive_date':
return date("Y-m-d H:i:s", $stripeObject->date);
case 'subscription_id':
return (string) $stripeObject->subscription;
case 'amount':
return (string) $stripeObject->amount_due / 100;
case 'amount_paid':
return (string) $stripeObject->amount_paid / 100;
case 'amount_remaining':
return (string) $stripeObject->amount_remaining / 100;
case 'currency':
return (string) mb_strtoupper($stripeObject->currency);
case 'status_id':
if ((bool)$stripeObject->paid) {
return 'Completed';
}
else {
return 'Pending';
}
case 'description':
return (string) $stripeObject->description;
}
break;
case 'Stripe\Subscription':
switch ($name) {
case 'frequency_interval':
return (string) $stripeObject->plan->interval_count;
case 'frequency_unit':
return (string) $stripeObject->plan->interval;
case 'plan_amount':
return (string) $stripeObject->plan->amount / 100;
case 'currency':
return (string) mb_strtoupper($stripeObject->plan->currency);
case 'plan_id':
return (string) $stripeObject->plan->id;
case 'plan_name':
return (string) $stripeObject->plan->name;
case 'plan_start':
return date("Y-m-d H:i:s", $stripeObject->start);
case 'cycle_day':
return date("d", $stripeObject->billing_cycle_anchor);
case 'subscription_id':
return (string) $stripeObject->id;
case 'status_id':
switch ($stripeObject->status) {
case \Stripe\Subscription::STATUS_ACTIVE:
return CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'In Progress');
case \Stripe\Subscription::STATUS_CANCELED:
return CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Cancelled');
}
case 'customer_id':
return (string) $stripeObject->customer;
}
break;
}
return NULL;
}
public static function getParam($name, $stripeObject) {
// Common parameters
switch ($name) {
case 'customer_id':
return (string) $stripeObject->customer;
case 'event_type':
return (string) $stripeObject->type;
case 'previous_plan_id':
if (preg_match('/\.updated$/', $stripeObject->type)) {
return (string) $stripeObject->data->previous_attributes->plan->id;
}
break;
}
return NULL;
}
}
......@@ -109,13 +109,12 @@ class CRM_Stripe_Customer {
/**
* @param $params
* @param $paymentProcessor
*
* @return \Stripe\ApiResource
* @throws \CiviCRM_API3_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public static function create($params, $paymentProcessor) {
public static function create($params) {
$requiredParams = ['contact_id', 'card_token', 'processor_id'];
// $optionalParams = ['email'];
foreach ($requiredParams as $required) {
......
......@@ -15,8 +15,8 @@ use CRM_Stripe_ExtensionUtil as E;
* @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
*/
function _civicrm_api3_stripe_customer_get_spec(&$spec) {
$spec['id']['title'] = ts("Stripe Customer ID");
$spec['id']['type'] = CRM_Utils_Type::T_STRING;
$spec['customer_id']['title'] = ts("Stripe Customer ID");
$spec['customer_id']['type'] = CRM_Utils_Type::T_STRING;
$spec['contact_id']['title'] = ts("CiviCRM Contact ID");
$spec['contact_id']['type'] = CRM_Utils_Type::T_INT;
$spec['processor_id']['title'] = ts("Payment Processor ID");
......@@ -25,7 +25,7 @@ function _civicrm_api3_stripe_customer_get_spec(&$spec) {
/**
* StripeCustomer.Get API
* This api will update the civicrm_stripe_customers table and add contact IDs for all known email addresses
* This api will get a customer from the civicrm_stripe_customers table
*
* @param array $params
* @see civicrm_api3_create_success
......@@ -33,10 +33,10 @@ function _civicrm_api3_stripe_customer_get_spec(&$spec) {
* @return array
*/
function civicrm_api3_stripe_customer_get($params) {
foreach ($params as $key => $value) {
$index = 1;
foreach ($params as $key => $value) {
switch ($key) {
case 'id':
case 'customer_id':
$where[$index] = "{$key}=%{$index}";
$whereParam[$index] = [$value, 'String'];
$index++;
......@@ -61,7 +61,7 @@ function civicrm_api3_stripe_customer_get($params) {
while ($dao->fetch()) {
$result = [
'id' => $dao->id,
'customer_id' => $dao->id,
'contact_id' => $dao->contact_id,
'processor_id' => $dao->processor_id,
];
......@@ -74,15 +74,15 @@ function civicrm_api3_stripe_customer_get($params) {
}
/**
* StripeCustomer.Get API specification
* StripeCustomer.delete API specification
*
* @param array $spec description of fields supported by this API call
* @return void
* @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
*/
function _civicrm_api3_stripe_customer_delete_spec(&$spec) {
$spec['id']['title'] = ts("Stripe Customer ID");
$spec['id']['type'] = CRM_Utils_Type::T_STRING;
$spec['customer_id']['title'] = ts("Stripe Customer ID");
$spec['customer_id']['type'] = CRM_Utils_Type::T_STRING;
$spec['contact_id']['title'] = ts("CiviCRM Contact ID");
$spec['contact_id']['type'] = CRM_Utils_Type::T_INT;
$spec['processor_id']['title'] = ts("Payment Processor ID");
......@@ -105,6 +105,41 @@ function civicrm_api3_stripe_customer_delete($params) {
return civicrm_api3_create_success([]);
}
/**
* StripeCustomer.create API specification
*
* @param array $spec description of fields supported by this API call
* @return void
* @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
*/
function _civicrm_api3_stripe_customer_create_spec(&$spec) {
$spec['customer_id']['title'] = ts("Stripe Customer ID");
$spec['customer_id']['type'] = CRM_Utils_Type::T_STRING;
$spec['customer_id']['api.required'] = TRUE;
$spec['contact_id']['title'] = ts("CiviCRM Contact ID");
$spec['contact_id']['type'] = CRM_Utils_Type::T_INT;
$spec['contact_id']['api.required'] = TRUE;
$spec['processor_id']['title'] = ts("Payment Processor ID");
$spec['processor_id']['type'] = CRM_Utils_Type::T_INT;
$spec['processor_id']['api.required'] = TRUE;
}
/**
* StripeCustomer.create API
* This api will add a stripe customer to CiviCRM
*
* @param array $params
* @see civicrm_api3_create_success
*
* @throws \Civi\Payment\Exception\PaymentProcessorException
* @return array
*/
function civicrm_api3_stripe_customer_create($params) {
CRM_Stripe_Customer::add($params);
return civicrm_api3_create_success([]);
}
/**
* Stripe.Customer.Updatecontactids API
* This api will update the civicrm_stripe_customers table and add contact IDs for all known email addresses
......@@ -181,10 +216,10 @@ function civicrm_api3_stripe_customer_updatecontactids($params) {
}
function _civicrm_api3_stripe_customer_updatestripemetadata_spec(&$spec) {
$spec['id']['title'] = E::ts("Stripe Customer ID");
$spec['id']['description'] = E::ts('If set only this customer will be updated, otherwise we try and update ALL customers');
$spec['id']['type'] = CRM_Utils_Type::T_STRING;
$spec['id']['api.required'] = FALSE;
$spec['customer_id']['title'] = E::ts("Stripe Customer ID");
$spec['customer_id']['description'] = E::ts('If set only this customer will be updated, otherwise we try and update ALL customers');
$spec['customer_id']['type'] = CRM_Utils_Type::T_STRING;
$spec['customer_id']['api.required'] = FALSE;
$spec['dryrun']['api.required'] = TRUE;
$spec['dryrun']['type'] = CRM_Utils_Type::T_BOOLEAN;
$spec['processor_id']['api.required'] = FALSE;
......@@ -207,7 +242,7 @@ function civicrm_api3_stripe_customer_updatestripemetadata($params) {
throw new CiviCRM_API3_Exception('Missing required parameter dryrun');
}
// Check params
if (empty($params['id'])) {
if (empty($params['customer_id'])) {
// We're doing an update on all stripe customers
if (!isset($params['processor_id'])) {
throw new CiviCRM_API3_Exception('Missing required parameters processor_id when using without a customer id');
......@@ -215,7 +250,7 @@ function civicrm_api3_stripe_customer_updatestripemetadata($params) {
$customerIds = CRM_Stripe_Customer::getAll($params['processor_id'], $params['options']);
}
else {
$customerIds = [$params['id']];
$customerIds = [$params['customer_id']];
}
foreach ($customerIds as $customerId) {
$customerParams = CRM_Stripe_Customer::getParamsForCustomerId($customerId);
......
......@@ -132,3 +132,188 @@ WHERE trxn_id=%1;";
}
return civicrm_api3_create_success($counts);
}
/**
* API to import a stripe subscription, create a customer, recur, contribution and optionally link to membership
* You run it once for each subscription and it creates/updates a recurring contribution in civicrm (and optionally links it to a membership).
*
* @param array $params
*
* @return array
* @throws \API_Exception
* @throws \CiviCRM_API3_Exception
* @throws \Stripe\Error\Api
*/
function civicrm_api3_stripe_subscription_import($params) {
civicrm_api3_verify_mandatory($params, NULL, ['subscription_id', 'contact_id', 'payment_processor_id']);
$paymentProcessor = \Civi\Payment\System::singleton()->getById($params['payment_processor_id'])->getPaymentProcessor();
// Now re-retrieve the data from Stripe to ensure it's legit.
\Stripe\Stripe::setApiKey($paymentProcessor['user_name']);
$stripeSubscription = \Stripe\Subscription::retrieve($params['subscription_id']);
// Create the stripe customer in CiviCRM
$customerParams = [
'customer_id' => CRM_Stripe_Api::getObjectParam('customer_id', $stripeSubscription),
'contact_id' => $params['contact_id'],
'processor_id' => (int) $params['payment_processor_id'],
];
$customer = civicrm_api3('StripeCustomer', 'get', $customerParams);
if (empty($customer['count'])) {
civicrm_api3('StripeCustomer', 'create', $customerParams);
}
// Create the recur record in CiviCRM
$contributionRecurParams = [
'contact_id' => $params['contact_id'],
'amount' => CRM_Stripe_Api::getObjectParam('plan_amount', $stripeSubscription),
'currency' => CRM_Stripe_Api::getObjectParam('currency', $stripeSubscription),
'frequency_unit' => CRM_Stripe_Api::getObjectParam('frequency_unit', $stripeSubscription),
'frequency_interval' => CRM_Stripe_Api::getObjectParam('frequency_interval', $stripeSubscription),
'start_date' => CRM_Stripe_Api::getObjectParam('plan_start', $stripeSubscription),
'processor_id' => $params['subscription_id'],
'trxn_id' => $params['subscription_id'],
'contribution_status_id' => CRM_Stripe_Api::getObjectParam('status_id', $stripeSubscription),
'cycle_day' => CRM_Stripe_Api::getObjectParam('cycle_day', $stripeSubscription),
'auto_renew' => 1,
'payment_processor_id' => $params['payment_processor_id'],
'payment_instrument_id' => !empty($params['payment_instrument_id']) ? $params['payment_instrument_id'] : 'Credit Card',
'financial_type_id' => !empty($params['financial_type_id']) ? $params['financial_type_id'] : 'Donation',
'is_email_receipt' => !empty($params['is_email_receipt']) ? 1 : 0,
'is_test' => isset($paymentProcessor['is_test']) && $paymentProcessor['is_test'] ? 1 : 0,
];
if ($params['recur_id']) {
$contributionRecurParams['id'] = $params['recur_id'];
}
$contributionRecur = civicrm_api3('ContributionRecur', 'create', $contributionRecurParams);
// Get the invoices for the subscription
$invoiceParams = [
'customer' => CRM_Stripe_Api::getObjectParam('customer_id', $stripeSubscription),
'limit' => 10,
//'due_date[lte]' => time(),
];
$stripeInvoices = \Stripe\Invoice::all($invoiceParams);
foreach ($stripeInvoices->data as $stripeInvoice) {
if (CRM_Stripe_Api::getObjectParam('subscription_id', $stripeInvoice) === $params['subscription_id']) {
if (!empty(CRM_Stripe_Api::getObjectParam('description', $stripeInvoice))) {
$sourceText = CRM_Stripe_Api::getObjectParam('description', $stripeInvoice);
}
elseif (!empty($params['contribution_source'])) {
$sourceText = $params['contribution_source'];
}
else {
$sourceText = 'Stripe: Manual import via API';
}
$contributionParams = [
'contact_id' => $params['contact_id'],
'total_amount' => CRM_Stripe_Api::getObjectParam('amount', $stripeInvoice),
'currency' => CRM_Stripe_Api::getObjectParam('currency', $stripeInvoice),
'receive_date' => CRM_Stripe_Api::getObjectParam('receive_date', $stripeInvoice),
'trxn_id' => CRM_Stripe_Api::getObjectParam('charge_id', $stripeInvoice),
'contribution_status_id' => CRM_Stripe_Api::getObjectParam('status_id', $stripeInvoice),
'payment_instrument_id' => !empty($params['payment_instrument_id']) ? $params['payment_instrument_id'] : 'Credit Card',
'financial_type_id' => !empty($params['financial_type_id']) ? $params['financial_type_id'] : 'Donation',
'is_test' => isset($paymentProcessor['is_test']) && $paymentProcessor['is_test'] ? 1 : 0,
'contribution_source' => $sourceText,
'contribution_recur_id' => $contributionRecur['id'],
];
$existingContribution = civicrm_api3('Contribution', 'get',
[
'contribution_test' => '',
'trxn_id' => $contributionParams['trxn_id']
]);
if (!empty($existingContribution['id'])) {
$contributionParams['id'] = $existingContribution['id'];
}
elseif ($params['contribution_id']) {
$contributionParams['id'] = $params['contribution_id'];
}
$contribution = civicrm_api3('Contribution', 'create', $contributionParams);
break;
}
}
// Link to membership record
// By default we'll match the latest active membership, unless membership_id is passed in.
if (!empty($params['membership_id'])) {
$membershipParams = [
'id' => $params['membership_id'],
'contribution_recur_id' => $contributionRecur['id'],
];
$membership = civicrm_api3('Membership', 'create', $membershipParams);
}
elseif (!empty($params['membership_auto'])) {
$membershipParams = [
'contact_id' => $params['contact_id'],
'options' => ['limit' => 1, 'sort' => "id DESC"],
'contribution_recur_id' => ['IS NULL' => 1],
'is_test' => !empty($paymentProcessor['is_test']) ? 1 : 0,
'active_only' => 1,
];
$membership = civicrm_api3('Membership', 'get', $membershipParams);
if (!empty($membership['id'])) {
$membershipParams = [
'id' => $membership['id'],
'contribution_recur_id' => $contributionRecur['id'],
];
$membership = civicrm_api3('Membership', 'create', $membershipParams);
}
}
$results = [
'subscription_id' => $params['subscription_id'],
'customer_id' => CRM_Stripe_Api::getObjectParam('customer_id', $stripeSubscription),
'recur_id' => $contributionRecur['id'],
'contribution_id' => !empty($contribution['id'])? $contribution['id'] : NULL,
'membership_id' => !empty($membership['id']) ? $membership['id'] : NULL,
];
return civicrm_api3_create_success($results, $params, 'StripeSubscription', 'import');
}
function _civicrm_api3_stripe_subscription_import_spec(&$spec) {
$spec['subscription_id']['title'] = ts("Stripe Subscription ID");
$spec['subscription_id']['type'] = CRM_Utils_Type::T_STRING;
$spec['subscription_id']['api.required'] = TRUE;
$spec['contact_id']['title'] = ts("Contact ID");
$spec['contact_id']['type'] = CRM_Utils_Type::T_INT;
$spec['contact_id']['api.required'] = TRUE;
$spec['payment_processor_id']['title'] = ts("Payment Processor ID");
$spec['payment_processor_id']['type'] = CRM_Utils_Type::T_INT;
$spec['payment_processor_id']['api.required'] = TRUE;
$spec['recur_id']['title'] = ts("Contribution Recur ID");
$spec['recur_id']['type'] = CRM_Utils_Type::T_INT;
$spec['contribution_id']['title'] = ts("Contribution ID");
$spec['contribution_id']['type'] = CRM_Utils_Type::T_INT;
$spec['membership_id']['title'] = ts("Membership ID");
$spec['membership_id']['type'] = CRM_Utils_Type::T_INT;
$spec['membership_auto']['title'] = ts("Link to existing membership automatically");
$spec['membership_auto']['type'] = CRM_Utils_Type::T_BOOLEAN;
$spec['membership_auto']['api.default'] = TRUE;
$spec['financial_type_id'] = [
'title' => 'Financial Type ID',
'name' => 'financial_type_id',
'type' => CRM_Utils_Type::T_INT,
'pseudoconstant' => [
'table' => 'civicrm_financial_type',
'keyColumn' => 'id',
'labelColumn' => 'name',
],
];
$spec['payment_instrument_id']['api.aliases'] = ['payment_instrument'];
$spec['contribution_source'] = [
'title' => 'Contribution Source (optional description for contribution)',
'type' => CRM_Utils_Type::T_STRING,
];
}
......@@ -17,9 +17,14 @@ The api commands are:
* `ppid` - Use the given Payment Processor ID. By default, uses the saved, live Stripe payment processor and throws an error if there is more than one.
* `noreceipt` - Set to 1 if you want to suppress the generation of receipts or set to 0 or leave out to send receipts normally.
### Additionally for upgrading:
## StripeCustomer
* `StripeCustomer.updatecontactids` - Used to migrate civicrm_stripe_customer table to match on contact_id instead of email address.
* `StripeCustomer.updatestripemetadata` - Used to update stripe customers that were created using an older version of the extension (adds name to description and contact_id as a metadata field).
## StripeSubscription
* `StripeSubscription.updatetransactionids` - Used to migrate civicrm_stripe_subscriptions to use recurring contributions directly.
* `StripeSubscription.copytrxnidtoprocessorid` - Used to copy trxn_id to processor_id in civicrm_contribution_recur table so we can use cancelSubscription. Hopefully this won't be needed in future versions of CiviCRM if we can pass more sensible values to the cancelSubscription function.
* `StripeSubscription.import` - Use to import subscriptions into CiviCRM that are in Stripe but not CiviCRM.
Accepts various parameters but requires: Payment Processor ID, Stripe subscription ID and CiviCRM contact ID.
![StripeSubscription.import](/images/StripeSubscription.import.png)
\ No newline at end of file
......@@ -2,8 +2,13 @@
Please do help improve this documentation by submitting a PR or contacting me.
## Configuration
All configuration is in the standard Payment Processors settings area in CiviCRM admin.
You will enter your "Publishable" & "Secret" key given by stripe.com.
### Stripe
Create an API key by logging in to your Stripe dashboard and selecting [API keys](https://dashboard.stripe.com/account/apikeys) from the left navigation. You can use the standard key, or you can click "Create rrestricted key" to have a more limited key. Example key restrictions are listed below.
### CiviCRM
All configuration is in the standard Payment Processors settings area in CiviCRM admin (**Administer menu » System Settings » Payment Processors**).
Add a payment processor and enter your "Publishable" & "Secret" keys given by stripe.com.
## Installation
There are no special installation requirements.
......@@ -16,3 +21,28 @@ More info on how to change: https://stripe.com/docs/upgrades#how-can-i-upgrade-
Go to _Account Settings_ -> _API Keys_ tab -> click _Upgrade available_ button.
Don't forget to update the webhook API version as well.
### Stripe API Key restrictions
If you prefer, you can restrict the permissions available to the API key you create. The below is an example that may have more permissions than is needed, but works with one-time payments, recurring payments, and the webhook check built into this extension. If a permission isn't listed below, leave it as *None*.
**Core resources**
Balance: *Read*
Charges: *Write*
Customers: *Write*
Disputes: *Write*
Events: *Read*
Products: *Write*
Sources: *Write*
Tokens: *Read*
**Billing resources**
Plans: *Write*
Subscriptions: *Write*
**Connect resources**
Application Fees: *Write*
**Orders resources**
SKUs: *Write*
**Webhook resources**
Webhook Endpoints: *Read* (required for the webhook system check)
![Example Stripe API Permissions](images/example_api_perms.png)
......@@ -344,8 +344,8 @@ CRM.$(function($) {
function getIsWebform(form) {
// Pass in the billingForm object
// If the form has the webform-client-form class then it's a drupal webform!
return form.hasClass('webform-client-form');
// If the form has the webform-client-form (drupal 7) or webform-submission-form (drupal 8) class then it's a drupal webform!
return form.hasClass('webform-client-form') || form.hasClass('webform-submission-form');
}
function getBillingForm() {
......@@ -368,6 +368,10 @@ CRM.$(function($) {
if (isWebform) {
$submit = $form.find('[type="submit"].webform-submit');
if (!$submit.length) {
// drupal 8 webform
$submit = $form.find('[type="submit"].webform-button--submit');
}
}
else {
$submit = $form.find('[type="submit"].validate');
......