Skip to content

9.2 Stripe & Cryptocurrency Payment

DA edited this page May 23, 2021 · 30 revisions

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.

Stripe


In this video you will learn how to accept payments with Caligrafy.


Setting up a Stripe

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

Configuring .env

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.

Test Data

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

Method 1: Simple card payment without authorization flows

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:

  1. Activate the payment in the Controller
use Caligrafy\Controller;

class PaymentController extends Controller {
    
    public function index()
    {
        // Activate Stripe Payment
        $this->activatePayment();
    }
    
}
  1. 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']) 
        ];
    }
    
}
  1. 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.

Method 2: Global payment for all types of cards

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.

  1. Activate the payment in the Controller (Similarly to step 1 from the other technique)
  2. 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()));
    }
}
  1. 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

Method 3: Checkout flow powered by Stripe

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.

  1. Activate the payment in the Controller (Similarly to step 1 from the other technique)
  2. 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()));
    }
}
  1. 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

Payment Methods

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 example USD
  • $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

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).

Setting up Stripe and Plaid

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

Configuring .env

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.

Test Data

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 a Payment

Creating an ACH payment in this framework is quick and easy. The payment is handled from the context of a Controller in 4 steps:

  1. Activate the payment in the Controller
use Caligrafy\Controller;

class PaymentController extends Controller {
    
    public function index()
    {
        // Activate Payment
        $this->activatePayment();
    }
    
}
  1. 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.

  1. 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));
         }
         
    }
    
}
  1. 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));
         }
         
    }
    
}
  1. 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.


Cryptocurrency

Caligrafy uses Coinbase as a gateway for accepting cryptocurrency.

Setting up Coinbase

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

Configuring .env

Coinbase Commerce provides API Keys. In the framework .env file, you need to provide this API Key:

CRYPTO_PAY_KEY= // <API Key>

Creating a Payment

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.

  1. 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));
    }
}
  1. 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.

Coinbase Commerce Methods

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



Next Section: Learn about Metadata & Social Rich Cards

Clone this wiki locally