DEV Community

Noel Minchow
Noel Minchow

Posted on

Simplify your Stripe integration with Paysly

(\ˈpāz-lē\ - like the pattern)

Historically, I have had a few projects where I wanted to use Stripe Elements to create in-line payments forms on static sites, but using stripe elements requires a backend server setup. You can find a bunch of tutorials and examples online to guide you through the setup of a basic web server to accept payments on your site using stripe (which is handy) but I was curious if I could create a generic solution to this problem.

And thus, Paysly was born!

disco

At its core, Paysly allows developers to create payment flows using Stripe Elements - all from the fronted. During development, I though it would also be cool if it supported the creation of dynamic Stripe Checkout flows from the frontent as well, and provided a way to verify both kinds of payments using JWTs, but more on that in a bit! First, an example:

Example

The Paysly api docs provide examples for creating recurring and one-time charges using Elements and Checkout - this example covers an end to end flow for one-time charges using Stripe Elements.

Setup

Before you begin, you will need a paysly account linked to a stripe account. After you sign up and link your account, you will be able to retrieve you keys from the paysly dashboard.

Implementation

The Paysly npm package is the lifeblood of Paysly. It exposes the Stripe Elements framework for you and allows you to create payments. So first, install the package:

npm install paysly
# or
yarn add paysly

and initialize:

const Paysly = require('paysly');
// replace 'pk_test_yourPublicKey-I3gcWtGXPuyWFRk2YD5' with your public key
// from the paysly dashboard
const paysly = await Paysly('pk_test_yourPublicKey-I3gcWtGXPuyWFRk2YD5');
// or
Paysly('pk_test_yourPublicKey-I3gcWtGXPuyWFRk2YD5').then((paysly) => {
  // your code here
});

Then, create an elements instance using paysly:

var elements = paysly.elements();

This elements instance is a full copy of the Stripe elements object. With it, you can do anything that you can do with the Stripe elements object. The rest of this guide exemplifies a basic flow, but you can also create an element however you would like. Stripe provides several examples to help you get started, or you can continue to follow the guide here.

To display an element on your site, set up the html containers:

<form action="/charge" method="post" id="payment-form">
  <div class="form-row">
    <label for="card-element">
      Credit or debit card
    </label>
    <div id="card-element">
      <!-- A Stripe Element will be inserted here. -->
    </div>

    <!-- Used to display form errors. -->
    <div id="card-errors" role="alert"></div>
  </div>

  <button>Submit Payment</button>
</form>

Style the element as you would like:

.StripeElement {
  box-sizing: border-box;

  height: 40px;

  padding: 10px 12px;

  border: 1px solid transparent;
  border-radius: 4px;
  background-color: white;

  box-shadow: 0 1px 3px 0 #e6ebf1;
  -webkit-transition: box-shadow 150ms ease;
  transition: box-shadow 150ms ease;
}

.StripeElement--focus {
  box-shadow: 0 1px 3px 0 #cfd7df;
}

.StripeElement--invalid {
  border-color: #fa755a;
}

.StripeElement--webkit-autofill {
  background-color: #fefde5 !important;
}

Then, create your element using javascript:

// Custom styling can be passed to options when creating an Element.
var style = {
  base: {
    color: '#32325d',
    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
    fontSmoothing: 'antialiased',
    fontSize: '16px',
    '::placeholder': {
      color: '#aab7c4'
    }
  },
  invalid: {
    color: '#fa755a',
    iconColor: '#fa755a'
  }
};

// Create an instance of the card Element.
var card = elements.create('card', {style: style});

// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');

// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
  var displayError = document.getElementById('card-errors');
  if (event.error) {
    displayError.textContent = event.error.message;
  } else {
    displayError.textContent = '';
  }
});

Finally, when your customer submits the form, create the charge.

Creating a Charge

Creating a charge is done in a single function call:

// Handle form submission.
const form = document.getElementById('payment-form');
form.addEventListener('submit', (event) => {
  event.preventDefault();
  paysly.createCharge(
    card, 
    {},
    { currency: 'usd', amount: 500 }
  ).then((result) => {
    // handle result
  }).catch((result) => {
    // handle validation or charge errors
  });
});

The paysly.createCharge function takes three parameters:

createCharge also returns a promise. You can perform simple UI updates by handling the resolution result, or display errors by handling it's rejection. If you wish to perform business logic based on the result of the payment you can verify the payment in your success handler.

(Optional) Verification

After a charge is successfully created using paysly.createCharge, it's promise will be resolved with a stripe charge object. A signed version of this object will be in the returned result's token property, as well:

paysly.createCharge(
 // ...
).then((result) => {
  // handle result
  sendTokenToYourServerForVerification(result.token);
});

To verify the payment, you will want to supply this token to a secure environment (typically a web server), then decode it and ensure it contains the data you expect. This can be done with one of the numerous JWT libraries.

When validating the result, the contained paid attribute is the simplest way to check if the charge succeeded. You should also verify that amount is the value that you expect.

Alternatively, all charges created here are just regular Stripe charges, so you can verify with any of Stripes other verification methods.


And that's it! Again, the Paysly api docs provide examples for creating recurring and one-time charges using both Elements and Checkout. It is also worth mentioning that these charges exist in your stripe account just like any other charge - paysly simply makes creating them easier.


Footnote:

Paysly is also completely compatible with Stripe's new react library:

That means you can pass the paysly package into Stripe's react component and everything just works!

magic

Top comments (0)