Simplify your Stripe integration with Paysly
Tags: showdev, javascript, npm, sripe
Published: 2020-03-12 14:09:31

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

Historically, I have had a few projects where I wanted to use [Stripe Elements](https://stripe.com/docs/stripe-js) to create in-line payments forms on static sites, but using stripe elements requires a backend server setup. You can find a [bunch](https://itnext.io/create-stripe-subscription-payments-using-react-aws-lambda-pt-1-setting-up-the-lambda-service-4e26501d30e0) [of](https://alligator.io/nodejs/intro-stripe-payments/) [tutorials](https://dev.to/bnevilleoneill/building-a-payments-system-with-react-and-stripe-5djc) and [examples](https://github.com/firebase/functions-samples/tree/master/stripe) [online](https://yos.io/2017/06/22/serverless-stripe/) 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](https://paysly.io) was born!

![disco](https://dev-to-uploads.s3.amazonaws.com/i/45qg83dyl2dihlv1jeaw.gif)

At its core, Paysly allows developers to create payment flows using [Stripe Elements](https://stripe.com/docs/stripe-js) - all from the fronted. During development, I though it would also be cool if it supported the creation of dynamic [Stripe Checkout](https://stripe.com/docs/payments/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](https://docs.paysly.io) provide examples for creating [recurring](https://docs.paysly.io/guides/recurring-charges.html) and [one-time](https://docs.paysly.io/guides/one-time-charges.html) 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](https://dashboard.paysly.io) 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](https://dashboard.paysly.io).

## Implementation

The [Paysly npm package](https://www.npmjs.com/package/paysly) is the lifeblood of Paysly. It exposes the Stripe Elements framework for you and allows you to create payments. So first, install the package:

```bash
npm install paysly
# or
yarn add paysly
```
and initialize:
```js
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:

```js
var elements = paysly.elements();
```

This `elements` instance is a full copy of [the Stripe elements object](https://stripe.com/docs/js/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](https://github.com/stripe/elements-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:
```html
<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:
```css
.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:

```js
// 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:

```js
// 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`](https://docs.paysly.io/api.html#createcharge) function takes three parameters:

- a [Stripe elements card element](https://docs.paysly.io/guides/one-time-charges.html#initialize-elements) (described above)
- [token data](https://stripe.com/docs/js/tokens_sources/create_token?type=cardElement#stripe_create_token-data) (pass in `{}` if you don't need to use any token data, as done in the example above)
- a charge configuration object, which accepts all [stripe charge creation arguments](https://stripe.com/docs/api/charges/create)

[`createCharge`](https://docs.paysly.io/api.html#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`](https://docs.paysly.io/api.html#createcharge), it's promise will be resolved with a [stripe charge object](https://stripe.com/docs/api/charges/object). A signed version of this object will be in the returned result's `token` property, as well:

```js
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](https://jwt.io/#libraries).

When validating the result, the contained [`paid` attribute](https://stripe.com/docs/api/charges/object#charge_object-paid) is the simplest way to check if the charge succeeded. You should also verify that [`amount`](https://stripe.com/docs/api/charges/object#charge_object-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](https://stripe.com/docs/payments/checkout/fulfillment).

---

And that's it! Again, the [Paysly api docs](https://docs.paysly.io) provide examples for creating [recurring](https://docs.paysly.io/guides/recurring-charges.html) and [one-time](https://docs.paysly.io/guides/one-time-charges.html) 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](https://github.com/stripe/react-stripe-js):

{% link https://dev.to/stripe/introducing-the-react-stripe-js-library-api-updates-and-new-guides-3501 %}

That means you can pass the paysly package into [Stripe's react component](https://stripe.com/docs/stripe-js/react#elements-props) and everything just works!

![magic](https://dev-to-uploads.s3.amazonaws.com/i/wo7x3z6od7f8o6pfiket.gif)