-
Notifications
You must be signed in to change notification settings - Fork 53
Add New Payment Gateway
While integrating payments, our goal was to provide an easy & intuitive interface which can lay the ground-work of adding/removing payment_methods and should be a no-brainer.
While we were discussing and finding ways, we came across commerce_billing package which was already integrating bogus-payment and stripe at the time.
We started analysing it for the stripe integration and it appealed us.
Next, we started looking at changes needed in commerce_billing to support braintree integration and have it as the basis to develop something on our own or adapt it.
Integrating braintree was a breeze and we decided to use & extend commerce_billing for payments
We documented the steps to add any new payment gateway as:
-
Create a module which should implement overridable functions in
Commerce.Billing.Gateways.Base
# web/gateways/new_payment_gateway.ex defmodule Nectar.Billing.Gateways.NewPaymentGateway do use Commerce.Billing.Gateways.Base # specific to payment gateway # Implement other functions too as needed from # [purchase, capture, void, refund, store, unstore] def authorize(amount, nonce, options \\ :empty) do {:ok} end end
-
Add a configuration to tell which module implements New Payment Gateway
# config/dev.secret.exs config :nectar, :new_payment_gateway, type: Nectar.Billing.Gateways.NewPaymentGateway
-
To leverage one process per payment gateway, we will start a Genserver as implemented in
Commerce.Billing.Worker
for new payment gateway too and will add as a children to App Supervisor# in lib/nectar.ex def start(_type, _args) do import Supervisor.Spec, warn: false ... children = [ ... # Note: *id* should be different to start same worker with different configuration. # *id* is optional parameter so can be skipped but workers won't start without it worker(Commerce.Billing.Worker, new_payment_gateway_configuration, id: :new_payment_gateway) ... ] # Note: Configuration parsing can change, if # way to define configuration changed def new_payment_gateway_configuration do worker_config = Application.get_env(:nectar, :new_payment_gateway) gateway_type = worker_config[:type] settings = %{} [gateway_type, settings, [name: :new_payment_gateway]] end ...
-
In
web/gateways/gateway.ex
, a pattern match need to be added for new payment gateway to get invoked, when chosen as payment_method of choice while processing order# web/gateways/gateway.ex defp do_authorize_payment(order, "new_payment_gateway", payment_method_params) do # Use Commerce.Billing instead of Module implementing authorize # to leverage GenServer created for each payment Gateway # Below, will dispatch `authorize` to the dedicated GenServer for it # which in turn will call App Module implementing `authorize` # Direct call like # Nectar.Billing.Gateway.NewPaymentGateway.authorize(order, payment_method_params["new_payment_gateway"]) # above will leave the GenServer created useless / idle # Refer web/gateways/braintree.ex and web/gateways/braintree_impl.ex for using call like above :) Commerce.Billing.authorize(:new_payment_gateway, String.to_float(Decimal.to_string(order.total)), "123", # Refer web/gateways/braintree.ex for better separation and extraction billing_address: %Commerce.Billing.Address{ street1: "House No - Unknown", street2: "Street Name", city: "City Name", region: "India", country: "India", postal_code: "121005" }, description: "Order No. #{order.id}" ) end
-
As available payment methods are fetched from DB and shown on order payment page.
It's better to add the new payment gateway in DB.
Please make sure that name used in
web/gateways/gateway.ex
while pattern-match should be same as in DB or make arrangements to make pattern-match behave correctly for new payment method -
Finally, make sure that needed parameters for new payment gateway can be asked from user and passed for processing.
Create a template as payment.new-payment-gateway-name.html.eex.
Note
new-payment-gateway-name
is used to find the template while displaying payment methods view, so this also have to be same as payment gateway name as stored in DB. -
Payment Methods can be enabled/disabled from Settings
Refer web/templates/admin/checkout/payment.braintree.html.eex and not braintree
You can also refer for final changes at once at [New Payment Gateway] Minimal Payment Gateway Integration #23