pin-payments
A wrapper for the pin.net.au API. MIT licensed.
Installation
Available via RubyGems. Install the usual way;
gem install pin-payments
Build Status
Usage
Prerequisites
You'll need to create an account at pin.net.au first.
Setup
Create an initializer, eg. pin.rb
, using keys from Pin's Your Account page.
Pin.setup secret_key: ENV['PIN_SECRET_KEY'], publishable_key: ENV['PIN_PUBLISHABLE_KEY'], mode: ENV['PIN_ENV']
The mode
should be :live
or :test
depending on which API you want to access. The publishable_key
is optional.
Alternatively, you could fetch keys from a YAML file, e.g. like this initializer:
pin_config_path = Rails.root.join 'config', 'pin.yml'
if File.exists?(pin_config_path)
configuration = YAML.load_file(pin_config_path)
raise "No environment configured for Pin for RAILS_ENV=#{Rails.env}" unless configuration[Rails.env]
Pin.setup configuration[Rails.env].symbolize_keys
end
and then in config/pin.yml
:
test:
secret_key: "TEST_API_SECRET"
publishable_key: "TEST_PUBLISHABLE_KEY"
mode: "test"
development:
secret_key: "TEST_API_SECRET"
publishable_key: "TEST_PUBLISHABLE_KEY"
mode: "test"
production:
secret_key: "LIVE_API_SECRET"
publishable_key: "LIVE_PUBLISHABLE_KEY"
mode: "live"
This allows you to inject pin.yml
at deployment time, so that the secret key can be kept separate from your codebase.
JavaScript Helpers
You'll probably want to create a form through which users can enter their details. Pin's guide will step you through this. The publishable key will be necessary and, if set, can be obtained by calling Pin.publishable_key
. So for example, you could have at the bottom of your form:
$('form.pin').pinForm('<%= Pin.publishable_key %>')
You also need to include Pin.js in pages that will talk to Pin via JavaScript. You can easily do this (and load the appropriate live or test version of pin.js) by doing:
<%= javascript_include_tag Pin.js_url %>
Charges
Creating a charge
def create
Pin::Charge.create email: '[email protected]',
description: '1 year of service', amount: 10000,
currency: 'AUD',
ip_address: params[:ip_address],
card_token: params[:card_token]
end
This will issue a once-off charge. Generally it's a good practice to do this in a background job and not directly in the controller. You can also create a charge against a customer token, once you have saved a customer (more details below).
Pin::Charge.create email: '[email protected]',
description: '1 year of service', amount: 10000,
currency: 'AUD',
ip_address: params[:ip_address],
customer_token: customer.token
Retrieving charges
# get all charges
Pin::Charge.all
# get a charge with token "ch_lfUYEBK14zotCTykezJkfg"
Pin::Charge.find("ch_lfUYEBK14zotCTykezJkfg")
# search for charges - see https://pin.net.au/docs/api/charges#search-charges for available parameters
Pin::Charge.search(query: 'refund', sort: :amount, start_date: 1.month.ago, end_date: '2013-08-01', direction: 'desc')
Customers
For a recurring charge, you may wish to create a customer record at Pin. To do this, either create a Card
object first, then a corresponding Customer
via the API; or use a card_token
returned from Pin.js
to create a customer. Note that in either case you may activate additional compliance provisions in Pin's Terms & Conditions.
Creating a customer
# this doesn't contact the API
card = Pin::Card.new number: '5520000000000000', expiry_month: '12', expiry_year: '2018', cvc: '123',
name: 'User Name', address_line1: 'GPO Box 1234', address_city: 'Melbourne',
address_postcode: '3001', address_state: 'VIC', address_country: 'Australia'
# create a customer using a card object
customer = Pin::Customer.create '[email protected]', card
# you can also create a customer using a card token - for example, in a controller
def create
customer = Pin::Customer.create '[email protected]', params[:card_token]
end
Retrieving a customer
# get all customers
Pin::Customer.all
# get a customer with token "cus_XZg1ULpWaROQCOT5PdwLkQ"
Pin::Customer.find("cus_XZg1ULpWaROQCOT5PdwLkQ")
Refunds
Refunds work based on charges, so you'll need a charge first.
charge = Pin::Charge.first
Create a refund:
# provide an amount to refund that amount - defaults to refunding the full amount
# both methods do the same thing
charge.refund!(250)
Pin::Refund.create(charge, 250)
Get refunds for this charge:
# both do the same thing
refunds = charge.refunds
refunds = Pin::Refund.all(charge)
Card Tokens
Given a credit card, store it in Pin and get a card token in exchange:
# contact the API and get a card token
card = Pin::Card.create number: '5520000000000000', expiry_month: '12', expiry_year: '2018', cvc: '123',
name: 'User Name', address_line1: 'GPO Box 1234', address_city: 'Melbourne',
address_postcode: '3001', address_state: 'VIC', address_country: 'Australia'
token = card.token
You can then use this token to create a customer or make a charge. If possible, it is better practice to create card tokens using Pin.js
and only pass on the required information (ie. the card token and IP address) to your server.
Errors
Errors from the API will result in aPin::APIError
exception being raised:
begin
response = Pin::Charge.create( ... )
rescue Pin::APIError => e
redirect_to new_payment_path, flash: { error: "Charge failed: #{e.message}" }
end
License
MIT
Contributors
https://github.com/ghiculescu/pin-payments/graphs/contributors