Skip to content

Instantly share code, notes, and snippets.

@kinglozzer
Last active January 22, 2021 15:02
Show Gist options
  • Save kinglozzer/de631125b7a94f15e15f760d15b1bfa1 to your computer and use it in GitHub Desktop.
Save kinglozzer/de631125b7a94f15e15f760d15b1bfa1 to your computer and use it in GitHub Desktop.
Stripe + SilverStripe Omnipay
<?php
class PaymentExtension extends DataExtension
{
private static $db = [
'StripePaymentIntentReference' => 'Varchar(255)'
];
}
<?php
class PurchaseServiceExtension extends Extension
{
public function onBeforeCompletePurchase(array &$data = [])
{
// Hack to get the payment, as silverstripe-omnipay doesn't currently
// provide a getPayment() method in PaymentService
$reflectionProperty = new ReflectionProperty(get_class($this->owner), 'payment');
$reflectionProperty->setAccessible(true);
$payment = $reflectionProperty->getValue($this->owner);
if ($payment->StripePaymentIntentReference) {
// Pass the Payment Intent reference with the transaction data to Stripe
$data['paymentIntentReference'] = $payment->StripePaymentIntentReference;
}
}
}
<?php
// Ensure $data includes the token created by Stripe Elements JS
$data['paymentMethod'] = $stripeToken;
// Initialise the payment process
$response = ServiceFactory::create()
->getService($payment, ServiceFactory::INTENT_PURCHASE)
->initiate($data);
if ($response->isRedirect()) {
$omnipayResponse = $response->getOmnipayResponse();
if ($omnipayResponse instanceof Omnipay\Stripe\Message\PaymentIntents\Response) {
// Store the Payment Intent reference for later...
$payment->StripePaymentIntentReference = $omnipayResponse->getPaymentIntentReference();
$payment->write();
}
return $response->redirectOrRespond();
}
/**
* Payments
*/
(() => {
const cardContainer = document.getElementById('card-element');
if (!cardContainer) {
return;
}
const init = () => {
const stripe = Stripe(window.stripePublishableKey, {
apiVersion: '2020-08-27'
});
const elements = stripe.elements();
const cardElement = elements.create('card', {
iconStyle: 'solid',
style: {
base: {
color: "#000000",
fontFamily: '"Montserrat", sans-serif',
fontSmoothing: "antialiased",
fontSize: "16px",
"::placeholder": {
color: "#707070"
}
},
invalid: {
color: "#840000",
iconColor: "#840000"
}
}
});
cardElement.mount(cardContainer);
const container = document.querySelector('.booking');
const submitButton = document.querySelector('button.js-pay');
const form = submitButton.form;
const errorElement = document.getElementById('card-errors');
submitButton.addEventListener('click', (event) => {
event.preventDefault();
errorElement.setAttribute('style', 'display: none;');
stripe.createPaymentMethod({
type: 'card',
card: cardElement
}).then((result) => {
if (result.error) {
// Inform the user if there was an error
errorElement.textContent = result.error.message;
errorElement.setAttribute('style', 'display: block;');
} else {
// Submit form
form.querySelector('input[name="StripeToken"]').value = result.paymentMethod.id;
form.submit();
}
});
});
};
window.addEventListener('DOMContentLoaded', init);
})();
@Makreig
Copy link

Makreig commented Sep 12, 2019

the line:

if ($omnipayResponse instanceof Omnipay\Stripe\Message\PaymentIntents\Response) {

needs to be replaced with:

if (is_a($omnipayResponse, 'Omnipay\Stripe\Message\PaymentIntents\Response')) {

on ss4 for some reason. the instanceof doesn't work for some reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment