- πΊπΈUnited States TomTech
Automatically closed because Drupal 7 security and bugfix support has ended β as of 5 January 2025. If the issue verifiably applies β to later versions, please reopen with details and update the version.
I'm looking to create a webservice for Stripe. Looking e.g. at the patch to Commerce Services https://www.drupal.org/node/2054163 β "Payments and targeted actions for payments" which enables payment creation etc.
I realise this is not strictly a "Commerce Stripe" issue but the expertise I need is more likely to be here rather than under "Commerce Services" in general (please feel free to correct me if I am wrong).
Our context is a webapp/native app creating an order and making payments in app but passing (POSTing) the order and payment to Drupal7 - so that in the background emails are sent and other rules are triggered - and allowing us to use the same backend for processing the order - packing delivery etc. (we have an existing established Drupal7 webshop.
We use Stripe Checkout without cardonfile.
So...
Looking at the Commerce Stripe code the relevant parts are:
$c = array(
'amount' => $charge['amount'],
'currency' => $currency_code,
'card' => $pane_values['stripe_token'],
'description' => $description,
);
// optional...
if (!empty($payment_method['settings']['receipt_email'])) {
$c['receipt_email'] = $order->mail;
}
commerce_stripe_add_metadata($c, $order);
// Let modules alter the charge object to add attributes.
drupal_alter('commerce_stripe_order_charge', $c, $order);
to make the information SENT to Stripe from the server.
Then the transaction is created:
$transaction = commerce_payment_transaction_new('commerce_stripe', $order->order_id); // <---------------------- THE CREATION OF THE PAYMENT!!!!
$transaction->instance_id = $payment_method['instance_id'];
$transaction->amount = $charge['amount'];
$transaction->currency_code = $currency_code;
/*
* save the transaction as pending. this will cause an exception to be thrown
* if the transaction cannot be saved. this prevents the scenario where it
* can go all the way through the try/catch below with success in stripe but
* failing to ever save the transaction. saving the transaction here also acts as
* an early catch to prevent the stripe charge from going through if the Drupal
* side will be unable to save it for some reason.
*/
$transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
if (!_commerce_stripe_commerce_payment_transaction_save($transaction)) {
return FALSE;
}
And then the call is make to Stripe to create the charge in a try/catch - and the transaction object in Drupal is updated according to the result:
try {
// Stripe does not appreciate $0 transfers.
if ($charge['amount'] > 0) {
$response = Stripe\Charge::create($c); // this is spot where payment is made... against Stripe - send "c" containing basic info and Stripe_token to stripe and get back result...
$transaction->remote_id = $response->id;
$transaction->payload[REQUEST_TIME] = $response->__toJSON();
$transaction->message = t('Payment completed successfully.');
$transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
_commerce_stripe_commerce_payment_transaction_save($transaction);
}
// If the total is $0 we just put the card on file.
}
catch (Exception $e) {
debug( NULL, "commerce_stripe_submit_form_SUBMIT:I8:make stripe charge:EXCEPTION occurred",'print_r');
drupal_set_message(t('We received the following error processing your card: :error
Please enter your information again or try a different card.',
array(':error' => $e->getMessage())), 'error');
watchdog('commerce_stripe', 'Following error received when processing card @stripe_error.',
array('@stripe_error' => $e->getMessage()), WATCHDOG_NOTICE);
$transaction->remote_id = $e->getHttpStatus();
$transaction->payload[REQUEST_TIME] = $e->jsonBody;
$transaction->message = t('Card processing error: @stripe_error', array('@stripe_error' => $e->getMessage()));
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
_commerce_stripe_commerce_payment_transaction_save($transaction);
return FALSE;
}
So the above is the way Commerce stripe "makes the payment" on the server side.
Looking now at the Commerce Services code - the patch for payments under - resources/payment.inc we see the creation of the payment object/entity:
/**
* Creates a new payment transaction on an order.
*/
function commerce_services_payment_create($data, $flatten_fields) {
// Ensure the create request specifies a valid payment method type.
/* if (empty($data['payment_method'])) {
return services_error(t('You must specify a valid payment method type'), 400);
}
*/
/* patch from torgosPizza: */
if (empty($data['method_id']) || !commerce_payment_method_load($data['method_id'])) {
return services_error(t('You must specify a valid payment method ID'), 400);
}
// Create the new payment transaction
$payment = commerce_payment_transaction_new($data['method_id'], $data['order_id']);
// Remove the method_id and order_id from the data array since they've been set.
unset($data['method_id'], $data['order_id']);
// Set the field and property data and save the payment.
commerce_services_set_field_values('commerce_payment_transaction', $payment, $data, $flatten_fields);
commerce_payment_transaction_save($payment);
// Add simplified fields to the payment object for certain field types.
commerce_services_decorate_entity('commerce_payment_transaction', $payment);
// Flatten field value arrays if specified. This must be the last operation
// performed as it breaks the standard field data model. An entity whose
// fields have thus been flattened is no longer wrappable or writable.
if ($flatten_fields == 'true') {
$payment = clone($payment);
commerce_services_flatten_fields('commerce_payment_transaction', $payment);
}
return $payment;
}
But here there's no code to send the charge to Stripe etc. and get the response as far as I can see - maybe I'm missing something.
My question is - how best to proceed?
1. Do I "hard code" the Stripe aspects from Commerce Stripe into the function commerce_services_payment_create from Commerce Services - doing a switch say on method_id being "commerce_stripe"? Or could this be more elegantly done with a hook_xxxx of some sort?
2. Or best of all, would simply creating (POSTing) a payment object of type Stripe on the existing order do all of this magically in the background! (i.e. make the call to Stripe to create the charge without me having to code anything) - this would be nice but I don't see the code that would do this anywhere which is why I'm thinking of 1. above.
(clearly I'd have to pass the stripe token in from the client in some way - in the "payment create" POST (or as an order field in a previous order create/update POST))
I'm sure this discussion is useful for anyone seeking to make any kind of payment via webservices in general - not just "Stripe users"
Thanks for any pointers
Closed: outdated
3.0
Code
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
Automatically closed because Drupal 7 security and bugfix support has ended β as of 5 January 2025. If the issue verifiably applies β to later versions, please reopen with details and update the version.