commerce_stripe_connect.module in Commerce Stripe 7.3
Adds support for Stripe Connect using a single site-wide client ID.
File
modules/commerce_stripe_connect/commerce_stripe_connect.moduleView source
<?php
/**
* @file
* Adds support for Stripe Connect using a single site-wide client ID.
*/
/**
* Implements hook_menu().
*/
function commerce_stripe_connect_menu() {
$items = array();
// Stripe platform administration.
$items['admin/commerce/config/stripe-platform'] = array(
'title' => 'Stripe platform configuration',
'description' => 'Register platform data, set application fee, and view connected accounts.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_stripe_platform_configuration_form',
),
'access arguments' => array(
'administer commerce stripe platform',
),
'file' => 'includes/commerce_stripe_connect.admin.inc',
);
// Connect or revoke Stripe platform access for the site account.
$items['admin/commerce/config/stripe-connect'] = array(
'title' => 'Stripe account access',
'description' => 'Manage your Standard Stripe account connection.',
'page callback' => 'commerce_stripe_connect_admin_page',
'access arguments' => array(
'commerce stripe connect site',
),
'file' => 'includes/commerce_stripe_connect.admin.inc',
);
$items['stripe-connect/oauth'] = array(
'title' => 'Stripe Connect Redirect Authorization',
'type' => MENU_CALLBACK,
'page callback' => 'commerce_stripe_connect_authorize',
'access callback' => 'commerce_stripe_connect_authorize_access',
);
return $items;
}
/**
* Implements hook_permission().
*/
function commerce_stripe_connect_permission() {
return array(
'administer commerce stripe platform' => array(
'title' => t('Administer Stripe platform settings'),
'description' => t('Allows users to register platform data and view connected accounts.'),
'restrict access' => TRUE,
),
'commerce stripe connect site' => array(
'title' => t('Connect site to Standard Stripe account'),
'description' => t('Allows users to connect the site to a Standard Stripe account or revoke access to it.'),
'restrict access' => TRUE,
),
);
}
/**
* Access callback: validates access to the Stripe Connect OAuth return URL.
*/
function commerce_stripe_connect_authorize_access() {
if (empty($_GET['state'])) {
return FALSE;
}
// Prevent CSRF attacks with token verification.
if (drupal_valid_token(check_plain($_GET['state']))) {
return TRUE;
}
return FALSE;
}
/**
* Page callback: processes a Stripe Connect OAuth return.
*/
function commerce_stripe_connect_authorize() {
// Error response.
if (!empty($_GET['error'])) {
// Malformed URL.
if (empty($_GET['error_description'])) {
drupal_not_found();
}
drupal_set_message(check_plain($_GET['error_description']), 'error');
drupal_goto('admin/commerce/config/stripe-connect');
}
// Verify that the URL includes scope and code values.
if (empty($_GET['scope']) || empty($_GET['code'])) {
drupal_not_found();
}
// Verify that the scope is read-write.
if ($_GET['scope'] != 'read_write') {
drupal_set_message(t('Stripe connect integration requires read/write access.'), 'error');
drupal_goto('admin/commerce/config/stripe-connect');
}
// All is well. Get the authorization code and fetch user's credentials.
$authorization_code = check_plain($_GET['code']);
$client_secret = commerce_stripe_connect_get_setting('platform_secret_key', '');
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => 'https://connect.stripe.com/oauth/token',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer ' . $client_secret,
),
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => http_build_query(array(
'client_secret' => $client_secret,
'code' => $authorization_code,
'grant_type' => 'authorization_code',
)),
));
$response = curl_exec($ch);
$response_body = drupal_json_decode($response);
if (!empty($response_body['error'])) {
drupal_set_message(check_plain($response_body['error_description']), 'error');
drupal_goto('admin/commerce/config/stripe-connect');
}
// Malformed data.
if (empty($response_body['stripe_user_id']) || empty($response_body['access_token']) || empty($response_body['stripe_publishable_key'])) {
drupal_not_found();
}
// Set the connected account ID and API credentials.
commerce_stripe_connect_set_setting('connected_account_id', check_plain($response_body['stripe_user_id']));
commerce_stripe_connect_set_setting('connected_secret_key', check_plain($response_body['access_token']));
commerce_stripe_connect_set_setting('connected_public_key', check_plain($response_body['stripe_publishable_key']));
// Redirect to the Stripe Connect page.
drupal_set_message(t('Your site has been connected to your Standard Stripe account.'));
drupal_goto('admin/commerce/config/stripe-connect');
}
/**
* Implements hook_commerce_stripe_order_charge_alter().
*/
function commerce_stripe_connect_commerce_stripe_order_charge_alter(&$charge, $order) {
// If developers use hook to specify a different application fee, do not overwrite.
if (!empty($charge['application_fee'])) {
return;
}
// Check that connected account is being used for API requests.
if (empty($order->payment_method_settings['use_connected_account']) || $order->payment_method_settings['use_connected_account'] != 'site account') {
return;
}
// Calculate and add application fee to the charge.
$connect_settings = commerce_stripe_connect_get_settings();
if ($connect_settings['application_fee_method'] == 'percentage') {
if (empty($connect_settings['application_fee_percentage'])) {
return;
}
$fee = $charge['amount'] * $connect_settings['application_fee_percentage'] / 100;
$fee = (int) round($fee);
}
else {
if (empty($connect_settings['application_fee_amount'])) {
return;
}
$fee = commerce_currency_decimal_to_amount($connect_settings['application_fee_amount'], $charge['currency']);
}
if ($fee > 0) {
// Maximum fee is order total charge minus 2.9% + $0.30 (the Stripe transaction fee).
$stripe_fee = (int) round(0.029 * $charge['amount'] + 30);
$max_fee = $charge['amount'] - $stripe_fee;
$charge['application_fee'] = min($fee, $max_fee);
}
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Provide option to proportionally refund application fees.
*/
function commerce_stripe_connect_form_commerce_stripe_refund_form_alter(&$form, &$form_state, $form_id) {
// Ensure the original transaction actually has transaction fees.
$transaction = $form_state['transaction'];
if (!empty($transaction->payload)) {
$timestamp = key($transaction->payload);
$payload = json_decode($transaction->payload[$timestamp]);
if (!empty($payload->application_fee)) {
$form['refund_application_fee'] = array(
'#type' => 'checkbox',
'#title' => t('Proportionally refund any application fees.'),
'#default_value' => TRUE,
'#weight' => 2,
);
$form['actions']['#weight'] = 3;
}
}
}
/**
* Implements hook_commerce_stripe_order_refund_alter().
*/
function commerce_stripe_connect_commerce_stripe_order_refund_alter(&$refund, $form_state) {
// If developers use hook to specify a refund application fee setting, do not overwrite.
if (!empty($refund['refund_application_fee'])) {
return;
}
if (!empty($form_state['values']['refund_application_fee'])) {
$refund['refund_application_fee'] = true;
}
}
/**
* Returns the default settings for the Stripe Connect module.
*/
function commerce_stripe_connect_default_settings() {
return array(
'platform_client_id' => '',
'platform_secret_key' => '',
'webhook_signing_secret' => '',
'application_fee_method' => 'percentage',
'application_fee_percentage' => '0',
'application_fee_amount' => '0',
'platform_currency' => '',
'connected_account_id' => '',
'connected_secret_key' => '',
'connected_public_key' => '',
);
}
/**
* Returns the Stripe Connect settings as an associative array.
*/
function commerce_stripe_connect_get_settings() {
return variable_get('commerce_stripe_connect_settings', commerce_stripe_connect_default_settings()) + commerce_stripe_connect_default_settings();
}
/**
* Returns the Stripe Connect setting value for the given setting key.
*/
function commerce_stripe_connect_get_setting($key, $default_value = NULL) {
$settings = commerce_stripe_connect_get_settings();
return isset($settings[$key]) ? $settings[$key] : $default_value;
}
/**
* Set the value for the given Stripe Connect setting key.
*/
function commerce_stripe_connect_set_setting($key, $value) {
$settings = commerce_stripe_connect_get_settings();
$settings[$key] = $value;
variable_set('commerce_stripe_connect_settings', $settings);
}