Eldøy Projects Pay Documentation
Eldøy Projects Pay makes it easy to start accepting payments for your web application.
Currently only Stripe Payments are supported.
Create a Stripe account
Log in to your Stripe dashboard, and create an account to use with your site. You need to activate the account to use live payments, but for now you can use test payments.
Create your gateway
Log in to Eldøy Projects Pay and create a site and then a gateway.
Fill in the following fields in the gateway form:
Name
The name of your gateway, e.g. "My Profitable Gateway".
Description
How you would describe the gateway, e.g. "Payment Gateway for My Profitable web site".
Publishable Key and Secret Key
The Publishable key
and Secret key
values are found in your API keys section in your Stripe account.
Webhook secret
First save your gateway now to see your gateway key, copy it, then click edit
to continue filling in the fields for your gateway.
Production
Go to the webhook section live environments and fill in https://pay.eldoy.com/api/webhook/${GATEWAY_KEY}
as your Endpoint URL.
Replace ${GATEWAY_KEY}
with the gateway key from the gateway list for your site in your Eldøy Projects Pay account.
Development
In development, forward events to your application:
stripe listen --forward-to http://pay.eldoy.test/webhook/{KEY}
This is the output:
> Ready! Your webhook signing secret is whsec_sZ7A6KxqeUIFHmQ4xbao1L7GqGX8bG06 (^C to quit)
Use this web hook secret as the value for the gateway you currently are editing.
You can override the webhook secret from the command line like this:
STRIPE_WEBHOOK_SECRET=whsec_sZ7A6KxqeUIFHmQ4xbao1L7GqGX8bG06 npm run dev
Trigger an event:
stripe trigger payment_intent.created
Event URL
The Event URL
should be the URL where you receive the Stripe event data whenever a plan changes, e.g. https://example.com/api/subscription/event. This is a POST
request and delivers JSON
data.
Success URL
The Success URL
should be the URL of wherever you want to return to after payments on your site, e.g. https://example.com. This is a GET
request and lands on one of your pages.
Cancel URL
The Cancel URL
should be the URL of where you want to return to if payments are canceled, e.g. https://example.com/subscription/cancel. This is a GET
request and lands on one of your pages.
Return URL
The Return URL
should be the URL of where you want to return to when payments are completed or updated, e.g. https://example.com/subscription/success. This is a GET
request and lands on one of your pages.
Activate payment portal
To start using the payment portal, go here to Save your settings: https://dashboard.stripe.com/test/settings/billing/portal
Stripe Tax settings
Make sure you've set up Stripe Tax for Norway:
https://dashboard.stripe.com/test/settings/tax
Click on "+ Add registration" and set up VAT to be collected immediately.
Setup on your own site
# Install stripe CLI
brew install stripe/stripe-cli/stripe
# Then login to your account:
stripe login
# Trigger specific event
stripe trigger customer.subscription.created
# See all events
stripe trigger --help
Create products
# Premium product
stripe products create \
--name="Billing Guide: Premium Service" \
--description="Premium service with extra features"
# Basic product
stripe products create \
--name="Billing Guide: Basic Service" \
--description="Basic service with minimum features"
Take note of the product ids:
// Premium
"id": "prod_JC31RjX75gOSvR"
// Basic
"id": "prod_JC32hnDrpkFCxc"
Create a price for each product with the product ids from the previous step:
# Premium price
stripe prices create \
-d product=prod_JC31RjX75gOSvR \
-d unit_amount=1500 \
-d currency=usd \
-d "recurring[interval]"=month \
-d nickname=premium
# Basic price
stripe prices create \
-d product=prod_JC32hnDrpkFCxc \
-d unit_amount=500 \
-d currency=usd \
-d "recurring[interval]"=month \
-d nickname=basic
Take note of the price ids:
// Premium
"id": "price_1IZeyJKHin97Q2E7NQSrQOIe"
// Basic
"id": "price_1IZeyiKHin97Q2E7kubhzcim"
Alternatively go to the products page in your Stripe account and create the products you are selling. Create a price for each product, you'll use the price ids later.
Set your Product to specify if VAT should be included or not.
Include the stripe library
In your layout, or on top of the checkout
page, add the stripe libary in a script tag:
<script src="https://js.stripe.com/v3/"></script>
Add a file in app/config/subscription.yml
which contains your public stripe key:
publishable_key: pk_live_KEY_FOUND_IN_STRIPE_DASHBOARD
Create the payment page
On your website, create a page called checkout. Switch out the price ids for your own price.
Creating payment sessions
First create a file in payment/session.js
:
module.exports = async function ($) {
await $.filters(['setup-site', 'authenticate', 'login-required'])
const email = $.account.email
const gateway_key = $.app.config.payment.gateway_key
const price_id = $.params.price_id
// Data here can be anything you want
// It will be sent back to your other web hooks
const data = {
account_id: $.account.id
}
// $.pay is the plugin you added in the previous step
const result = await $.pay('/session/create', {
values: {
email,
gateway_key,
price_id,
data
}
})
return result
}
Configuration
Add a config file called app/config/payment.yml
with this content:
host: http://pay.eldoy.test
gateway_key: cl9sdi8ce0000bvlphxikh1y9
publishable_key: pk_test_51Lx7LgKbXwCmfxbVN4l3oTPJTika8MOy9rqQVTMuAbod87a32RLPO0NSPt2PAr1DdhI1JrchQcjbF4PDYZsthJYx00APp8RLtp
Add a app/config/payment.production.yml
file for live payments:
host: http://pay.eldoy.com/api
gateway_key: cl9sdi8ce0000bvlphxikh1y9
publishable_key: pk_live_51Lx7LgKbXwCmfxbVN4l3oTPJTika8MOy9rqQVTMuAbod87a32RLPO0NSPt2PAr1DdhI1JrchQcjbF4PDYZsthJYx00APp8RLtp
Setting up plugin
Then set up a plugin in plugins/pay.js
:
const waveorb = require('waveorb-client')
module.exports = async function (app) {
return waveorb(app.config.payment.host)
}
Adding event action
Add a web hook in actions/subscription/event.js
:
module.exports = async function ($) {
await $.allow({
data: [
'type',
'subscription_id',
'customer_id',
'product_id',
'price_id',
'metadata'
]
})
await $.validate({
data: {
type: {
required: true,
is: 'string'
},
subscription_id: {
required: true,
is: 'string'
},
customer_id: {
required: true,
is: 'string'
},
product_id: {
required: true,
is: 'string'
},
price_id: {
required: true,
is: 'string'
},
'metadata.account_id': {
required: true,
is: 'string'
}
}
})
// Set up account from metadata
await $.filters(['metadata-account'])
const { data } = $.params
const { type } = data
if (type == 'customer.subscription.created') {
console.log('Handle subscription created')
return await $.app.flows.subscription.create($)
} else if (type == 'customer.subscription.updated') {
console.log('Handle subscription updated')
return await $.app.flows.subscription.update($)
} else if (type == 'customer.subscription.deleted') {
console.log('Handle subscription deleted')
return await $.app.flows.subscription.delete($)
}
return { ok: true }
}
Testing payments
Use the card 4242 4242 4242 4242
with any future date and three-digit CVC.
Delete test data
To delete all Stripe test data, go to developers section of your dashboard.