-
-
Notifications
You must be signed in to change notification settings - Fork 2
9.2 Stripe & Cryptocurrency Payment
Accepting payments is a key success factor for any e-commerce application. Choosing the right service that balances security, ease of integration, cost and widespread availability is a challenging decision. This framework selected Stripe as its primary payment service and integrates it seamlessly at its core. For Cryptocurrency, this framework uses Coinbase.
In this video you will learn how to accept payments with Caligrafy.
In order to accept payments through this framework, a Stripe account needs to be created.
Open a free account with Stripe here
Once you open an account, Stripe provides you with a pair of local and production keys. You can get these keys from the Developers section
Stripe provides a pair of a Publishable Key
and a Secret Key
for a production environment and another one for a test environment.
In the framework .env
file, you need to provide these keys:
PAY_PUBLIC_KEY_TEST= // <Publishable Key for Test Data>
PAY_PRIVATE_KEY_TEST= // <Secret Key for Test Data>
PAY_PUBLIC_KEY_PRODUCTION= // <Publishable Key for Production>
PAY_PRIVATE_KEY_PRODUCTION= // <Secret Key for Production>
You need to make sure that in the .env
of the development machine you set APP_ENV=local
and on the production machine you set APP_ENV=production
.
Stripe provides test credit cards to test the payment gateway on a development machine. The test credit card can only be used with the Test Data pair of keys.
-
credit card number:
4242 4242 4242 4242
-
expiry year:
any year in the future
-
expiry month:
any month
-
CVC:
any combination of 3 or 4 numbers
Creating a payment for cards not requiring secure authorization flows by the issuer is quick and easy. The payment can be handled from the context of a Controller
. To illustrate this, let's assume that we created a view
that has a form containing the card number
, the expiry year
, the expiry month
and the CVC
.
Visit the Views section to learn more about creating forms with Pug
In order to process the payment, a payment controller needs to be created to receive the posted card values and to create a Stripe transaction:
- Activate the payment in the
Controller
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Stripe Payment
$this->activatePayment();
}
}
- Get the card inputs from the form
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Stripe Payment
$this->activatePayment();
// Create a card object from the posted information
$parameters = $this->request->parameters(); // fetches the inputs from the form
$card = [
'card' => array(
'number' => $parameters['number'],
'exp_month' => $parameters['exp_month'],
'exp_year' => $parameters['exp_year'],
'cvc' => $parameters['cvc'])
];
}
}
- Create a payment transaction
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Stripe Payment
$this->activatePayment();
// Create a card object from the posted information
$parameters = $this->request->parameters(); // fetches the inputs from the form
$card = [
'card' => array(
'number' => $parameters['number'],
'exp_month' => $parameters['exp_month'],
'exp_year' => $parameters['exp_year'],
'cvc' => $parameters['cvc'])
];
// Create a payment transaction
$this->payment->createTransaction(1000, 'USD', $card);
}
}
And that's it, you can verify in the Test Data Dashboard on Stripe that the charge was submitted.
Creating a payment that works for all types of cards globally needs a mechanism that is capable of handling any additional authorizations that the card issuer requires (i.e 3DSecure). With the Caligrafy integration of Stripe, you can get card payment up and ready in no time.
- Activate the payment in the
Controller
(Similarly to step 1 from the other technique) - Create a payment intent from the inputs
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Stripe Payment
$this->activatePayment();
// Create a payment intent from the posted information
$parameters = $this->request->parameters(); // fetches the inputs from the form
// The payment intent takes at the very least an amount and a currency
$result = $this->payment->createPaymentIntent(1000, 'USD');
if ($result['action_success']) {
$intent = $result['data']->client_secret;
} else {
$intent = null;
}
// Return a clientSecret and the stripe publicKey to the view
return view('default/pages/payment', array('clientSecret' => $intent, 'publicKey' => $this->payment->getPublicKey()));
}
}
- Hand-off the payment intent to the view
The controller needs to hand-off the payment to the view so that the Stripe client handles the entire payment flow. Caligrafy provides a payment page as an example default/pages/payment.pug
.
2 parameters must be returned to that page: clientSecret
from the intent and publicKey
which is the stripe publishable key that can already be fetched from the payment attribute of the controller.
[...]
// Return a clientSecret and the stripe publicKey to the view
return view('default/pages/payment', array('clientSecret' => $intent, 'publicKey' => $this->payment->getPublicKey()));
[...]
Don't forget to create routes to these controllers before testing
The third method is plug and play and it allows you to start accepting different types of payments very quickly without the burden of developing it yourself. Stripe takes care of it all for you.
- Activate the payment in the
Controller
(Similarly to step 1 from the other technique) - Create a checkout session
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Stripe Payment
$this->activatePayment();
// get the current url to bring back the customer to this page upon failure or success. If desired
$currentUrl = session('base').sanitizePath($_SERVER['REQUEST_URI']);
$result = $this->payment->createCheckout(2000, 'usd', 1, array('name' => 'T-shirt'), $currentUrl, $currentUrl);
if ($result['action_success']) {
$sessionId = $result['data']->id;
} else {
$sessionId = null;
}
// Pass the sessionId and the Stripe public key to the view
return view('default/pages/checkout', array('sessionId' => $sessionId, 'publicKey' => $this->payment->getPublicKey()));
}
}
- Hand-off the checkout session to the view
The controller needs to hand-off the session to the view so that the Stripe client handles the entire payment flow. Caligrafy provides a payment page as an example default/pages/checkout.pug
.
2 parameters must be returned to that page: sessionId
from the intent and publicKey
which is the stripe publishable key that can already be fetched from the payment attribute of the controller.
[...]
// Pass the sessionId and the Stripe public key to the view
return view('default/pages/checkout', array('sessionId' => $sessionId, 'publicKey' => $this->payment->getPublicKey()));
[...]
Don't forget to create routes to these controllers before testing
This framework uses 3 different methods to execute payments through Stripe.
// Method 1: Using charges for cards without authorization flows
public function createTransaction($amount, $currency, $card, $receipt_email = null, $metadata = null, $description = '')
// Method 2: Using payment intents for all types of cards
public function createPaymentIntent($amount, $currency, $metadata = array(), $receipt_email = null, $description = '')
// Method 3: Using an integrated checkout session
public function createCheckout($amount = 1000, $currency = 'usd', $quantity = 1, $productData = array(), $successUrl = '', $cancelUrl = '', $customerEmail = null, $locale = null, $paymentType = ['card'])
-
$amount
: This is the amount in cents -
$currency
: This is the currency string. For exampleUSD
-
$card
: This is an array that represents a credit cards, bank account or pii as described in the Stripe Documentation. -
$receipt_email
: This is the customer's email. When defined an automatic email will be sent if the email settings in your stripe allow for sending receipts. -
$metadata
: This is an array that represents any additional metadata that you would want to append to the transaction -
$description
: This is a text description that can be appended to the transaction -
$productData
: This is an array that represents any additional information about the product that needs to appear in the checkout process -
$successUrl
: This defines the url to redirect the checkout flow to upon successful completion -
$cancelUrl
: This defines the url to redirect the checkout flow to upon incompletion -
$paymentType
: This is an array that represents the different payment types that the checkout flow needs to support -
locale
: Defines the locale for language and formats of the checkout flow -
customer_email
: Prepopulates the email of the customer in the checkout flow
ACH payments are bank transfers. With Caligrafy, you can have your buyers pay directly from their bank accounts in a very user-friendly flow. Caligrafy uses Stripe in conjunction with Plaid (a Stripe partner).
In order to accept payments through this framework, a Stripe and a Plaid accounts need to be created.
Open a free account with Stripe here
Open a free account with Plaid here
Once you open the accounts, Stripe provides you with a pair of local and production keys. You can get these keys from the Developers section
Plaid provides you with a set of keys and secrets. You will need to get the client_id
, public_key
, Sandbox secret
and production secret
from the Plaid dashboard. Note that you will need to request access from Plaid for the production information. Meanwhile, you can use the development secret
for production
.
You can get these keys from the Plaid Dashboard
In the framework .env
file, you need to provide the Stripe keys:
PAY_PUBLIC_KEY_TEST= // <Publishable Key for Test Data>
PAY_PRIVATE_KEY_TEST= // <Secret Key for Test Data>
PAY_PUBLIC_KEY_PRODUCTION= // <Publishable Key for Production>
PAY_PRIVATE_KEY_PRODUCTION= // <Secret Key for Production>
And, the Plaid keys:
ACH_ACTIVATE=true
ACH_CLIENT_ID=// <Client ID>
ACH_SANDBOX_SECRET= // <Sandbox Secret>
ACH_PRODUCTION_SECRET= // <Production Or Development Secret>
You need to make sure that in the .env
of the development machine you set APP_ENV=local
and on the production machine you set APP_ENV=production
.
The workflow is very user-friendly. Users select their financial institution and they enter their bank credentials. Plaid provides the following credentials that could be entered for any bank selected:
- username:
user_good
- password:
pass_good
Creating an ACH payment in this framework is quick and easy. The payment is handled from the context of a Controller
in 4 steps:
- Activate the payment in the
Controller
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Payment
$this->activatePayment();
}
}
- Create a Link Token
Your application needs to first request a Link Token from Plaid by using the method
createLinkToken()
.
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Payment
$this->activatePayment();
// Create a Link token
$token = $this->payment->createLinkToken();
}
}
The created token is passed on to the client-side view (step #5 below). When the user completes the Plaid flow, a public token is posted for the server to use in step #3.
- Establish a link with the Bank
In order to establish a link with the bank you need to use the method
linkBankInformation($public_token, $account_id)
.
The public_token
and the account_id
are provided by the Plaid ACH module to Controller
. You therefore need to fetch and then pass them to the method. If there are no public_token
and account_id
available, then you will need to redirect them to the view
where you intend to include the ACH module (refer to step #5).
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Payment
$this->activatePayment();
// Create a Link token
$token = $this->payment->createLinkToken();
// Fetch the public_token and the account_id
$parameters = $this->request->parameters;
$publicToken = isset($parameters['public_token'])? $parameters['public_token'] : null;
$accountId = isset($parameters['account_id'])? $parameters['account_id'] : null;
// Pass them to the method when available
if ($publicToken && $accountId) {
$response = $this->payment->linkBankInformation($publicToken, $accountId);
} else {
// Pass the token to the view that contains the ACH module from step #5
return view('default/index', array('token' => $token));
}
}
}
- Create a transaction
So far, we just established a connect with the bank and tokenized the user's bank information. In this step we need to charge the bank account. You will need to use the same method that was used for credit cards createTransaction(...)
use Caligrafy\Controller;
class PaymentController extends Controller {
public function index()
{
// Activate Payment
$this->activatePayment();
// Create a Link token
$token = $this->payment->createLinkToken();
// Fetch the public_token and the account_id
$parameters = $this->request->parameters;
$publicToken = isset($parameters['public_token'])? $parameters['public_token'] : null;
$accountId = isset($parameters['account_id'])? $parameters['account_id'] : null;
// Pass them to the method when available
if ($publicToken && $accountId) {
$response = $this->payment->linkBankInformation($publicToken, $accountId);
// create a charge if you have the bank token
$token = isset($response['token'])? $response['token'] : null;
if ($token) {
dump($this->payment->createTransaction(1000, 'USD', $token));
}
} else {
// Pass the token to the view that contains the ACH module from step #5
return view('default/index', array('token' => $token));
}
}
}
- Add the ACH module to the
View
The Plaid Link module can be added very easily to your view. It is a button that will engage users in the Plaid bank linking workflow that does it all for you!
extends master/layoutblocks
block content
include modules/ach
The ach.pug
is located in default/modules/
. Make sure that the include uses a relative path to that file.
And that is it! You can go ahead and test it with the test data provided.
Caligrafy uses Coinbase as a gateway for accepting cryptocurrency.
In order to accept crytocurrency payments through this framework, a Coinbase account needs to be created.
Open a free account with Coinbase Commerce here
Once you open an account, Coinbase Commerce provides you with an API key. You can get this key from the User Settings
Coinbase Commerce provides API Keys. In the framework .env
file, you need to provide this API Key:
CRYPTO_PAY_KEY= // <API Key>
Creating a cryptocurrency payment in this framework is quick and easy. The payment can be handled from the context of a Controller
.
In order to accept cryptocurrencies, a charge needs to be created from the controller and the resulting Coinbase checkout URL (that is the url that provides an out-of-the-box checkout user interface) needs to be passed to the view.
- Create a cryptocurrency charge transaction
use Caligrafy\Controller;
use Caligrafy\CryptoPayment;
class PaymentController extends Controller {
public function index()
{
// Activate Coinbase Commerce Payment
$crypto = new CryptoPayment();
// Create a payment transaction
$transaction = $crypto->createTransaction(10, 'USD', array('name' => 'Product Name', 'description' => 'description goes here'));
return view('<name of view>', array('cryptourl' => $transaction->hosted_url));
}
}
- Add a Cryptocurrency Button
Caligrafy provides a ready-to-use checkout button. The module can be found in default/modules/cryptopayment.pug
.
This module can be changed, personalized to the need and should be included in any view
that you create by adding the following line:
include path-to-module/cryptopayment
And that's it, you can create a route and test it out.
This framework provides several methods to interface with the Coinbase Commerce API.
public function createTransaction($amount, $currency, $charge, $metadata = array(), $redirectUrl = '', $cancelUrl = '')
public function cancelTransaction($id)
public function getCharges()
public function getCharge($chargeId) // retrieves the charge by id
public function getChargeStatus($chargeId) // Gets the latest status on the charge