Pay comes with a lot of configuration out of the box for you, but you'll need to add your API tokens for your payment provider.
Pay automatically looks up credentials for each payment provider. We recommend storing them in the Rails credentials.
You'll need to add your API keys to your Rails credentials. You can do this by running:
rails credentials:edit --environment=developmentThey should be formatted like the following:
stripe:
private_key: xxxx
public_key: yyyy
webhook_receive_test_events: true
signing_secret:
- aaaa
- bbbb
braintree:
private_key: xxxx
public_key: yyyy
merchant_id: aaaa
environment: sandbox
paddle_billing:
client_token: aaaa
api_key: yyyy
signing_secret: pdl_ntfset...
environment: sandbox
paddle_classic:
vendor_id: xxxx
vendor_auth_code: yyyy
public_key_base64: MII...==
environment: sandbox
lemon_squeezy:
api_key: xxxx
store_id: yyyy
signing_secret: aaaaYou can also nest these credentials under the Rails environment if using a shared credentials file.
development:
stripe:
private_key: xxxx
# ...Pay will also check environment variables for API keys:
STRIPE_PUBLIC_KEYSTRIPE_PRIVATE_KEYSTRIPE_SIGNING_SECRETSTRIPE_WEBHOOK_RECEIVE_TEST_EVENTSBRAINTREE_MERCHANT_IDBRAINTREE_PUBLIC_KEYBRAINTREE_PRIVATE_KEYBRAINTREE_ENVIRONMENTPADDLE_BILLING_API_KEYPADDLE_BILLING_CLIENT_TOKENPADDLE_BILLING_SIGNING_SECRETPADDLE_BILLING_ENVIRONMENTPADDLE_CLASSIC_VENDOR_IDPADDLE_CLASSIC_VENDOR_AUTH_CODEPADDLE_CLASSIC_PUBLIC_KEYPADDLE_CLASSIC_PUBLIC_KEY_FILEPADDLE_CLASSIC_PUBLIC_KEY_BASE64PADDLE_CLASSIC_ENVIRONMENTLEMON_SQUEEZY_API_KEYLEMON_SQUEEZY_STORE_IDLEMON_SQUEEZY_SIGNING_SECRET
Tip
Are you using any of these payment processors for the very first time? Take a look at their respective configuration doc for generating these keys:
As per the guidance from https://support.stripe.com/questions/connect-account-webhook-configurations: "When a connected account is linked solely in live mode to your platform, both live and test events are sent to your live Connect Webhook Endpoint." Therefore, you can set this to false if you wish to receive only live events in Production.
If you want to modify the Stripe SCA template or any other views, you can copy over the view files using:
bin/rails generate pay:viewsIf you want to modify the email templates, you can copy over the view files using:
bin/rails generate pay:email_viewsEmails can be enabled/disabled as a whole by using the send_emails configuration option or independently by
using the emails configuration option as shown in the configuration section below (all emails are enabled by default).
When enabled, the following emails will be sent when:
- A payment action is required
- A payment failed
- A charge succeeded
- A charge was refunded
- A yearly subscription is about to renew
- A subscription trial is about to end
- A subscription trial has ended
Need to make some changes to how Pay is used? You can create an initializer config/initializers/pay.rb
Pay.setup do |config|
# For use in the receipt/refund/renewal mailers
config.business_name = "Business Name"
config.business_address = "1600 Pennsylvania Avenue NW"
config.application_name = "My App"
config.support_email = "Business Name <support@example.com>"
config.default_product_name = "default"
config.default_plan_name = "default"
config.automount_routes = true
config.routes_path = "/pay" # Only when automount_routes is true
# All processors are enabled by default. If a processor is already implemented in your application, you can omit it from this list and the processor will not be set up through the Pay gem.
config.enabled_processors = [:stripe, :braintree, :paddle_billing, :paddle_classic, :lemon_squeezy]
# To disable all emails, set the following configuration option to false:
config.send_emails = true
# By default emails are sent via Pay::UserMailer which inherits from Pay::ApplicationMailer. Instead, you may wish to inherit from ApplicationMailer, or use a different mailer entirely.
config.parent_mailer = "ApplicationMailer"
config.mailer = "MyCustomPayMailer"
# All emails can be configured independently as to whether to be sent or not. The values can be set to true, false or a custom lambda to set up more involved logic. The Pay defaults are show below and can be modified as needed.
config.emails.payment_action_required = true
config.emails.payment_failed = true
config.emails.receipt = true
config.emails.refund = true
# This example for subscription_renewing only applies to Stripe, therefore we supply the second argument of price
config.emails.subscription_renewing = ->(pay_subscription, price) {
(price&.type == "recurring") && (price.recurring&.interval == "year")
}
config.emails.subscription_trial_will_end = true
config.emails.subscription_trial_ended = true
# Customize who receives emails. Useful when adding additional recipients other than the Pay::Customer. This defaults to the pay customer's email address.
# config.mail_to = -> { "#{params[:pay_customer].customer_name} <#{params[:pay_customer].email}>" }
# Customize mail() arguments. By default, only includes { to: }. Useful when you want to add cc, bcc, customize the mail subject, etc.
# config.mail_arguments = ->(mailer, params) {
# {
# to: Pay.mail_recipients.call(mailer, params)
# }
# }
endPay enqueues ActiveJob work in two places you should be aware of:
- Webhooks – When a payment provider posts a webhook, Pay records the payload and enqueues
Pay::Webhooks::ProcessJobto run the handlers. If jobs are not processed, charges, subscriptions, and other provider events will not update your application data. - Customer sync – If a user's email is updated, Pay enqueues
Pay::CustomerSyncJobto sync the email with the payment processors they have set up.
Configure config.active_job.queue_adapter for your app. With adapters such as Sidekiq or Solid Queue, you must run a worker process (for example the sidekiq executable, or bin/jobs for Solid Queue) anywhere you need that work to run. With the :inline adapter, jobs run immediately in the same process and no worker is required, which is convenient for tests but unusual for production webhooks under load. Active Job basics
# config/application.rb
config.active_job.queue_adapter = :sidekiqSee Customers