class ActiveMerchant::Billing::PinGateway

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/pin.rb, line 14
def initialize(options = {})
  requires!(options, :api_key)
  super
end

Public Instance Methods

authorize(money, creditcard, options = {}) click to toggle source

Authorize an amount on a credit card. Once authorized, you can later capture this charge using the charge token that is returned.

# File lib/active_merchant/billing/gateways/pin.rb, line 68
def authorize(money, creditcard, options = {})
  options[:capture] = false

  purchase(money, creditcard, options)
end
capture(money, token, options = {}) click to toggle source

Captures a previously authorized charge. Capturing only part of the original authorization is currently not supported.

# File lib/active_merchant/billing/gateways/pin.rb, line 76
def capture(money, token, options = {})
  commit(:put, "charges/#{CGI.escape(token)}/capture", { amount: amount(money) }, options)
end
purchase(money, creditcard, options = {}) click to toggle source

Create a charge using a credit card, card token or customer token

To charge a credit card: purchase(, [creditcard hash], …) To charge a customer: purchase(, [token], …)

# File lib/active_merchant/billing/gateways/pin.rb, line 23
def purchase(money, creditcard, options = {})
  post = {}

  add_amount(post, money, options)
  add_customer_data(post, options)
  add_invoice(post, options)
  add_creditcard(post, creditcard)
  add_address(post, creditcard, options)
  add_capture(post, options)
  add_metadata(post, options)
  add_3ds(post, options)
  add_platform_adjustment(post, options)

  commit(:post, 'charges', post, options)
end
refund(money, token, options = {}) click to toggle source

Refund a transaction

# File lib/active_merchant/billing/gateways/pin.rb, line 62
def refund(money, token, options = {})
  commit(:post, "charges/#{CGI.escape(token)}/refunds", { amount: amount(money) }, options)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 105
def scrub(transcript)
  transcript.
    gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
    gsub(/(number\\?":\\?")(\d*)/, '\1[FILTERED]').
    gsub(/(cvc\\?":\\?")(\d*)/, '\1[FILTERED]')
end
store(creditcard, options = {}) click to toggle source

Create a customer and associated credit card. The token that is returned can be used instead of a credit card parameter in the purchase method

# File lib/active_merchant/billing/gateways/pin.rb, line 41
def store(creditcard, options = {})
  post = {}

  add_creditcard(post, creditcard)
  add_customer_data(post, options)
  add_address(post, creditcard, options)
  commit(:post, 'customers', post, options)
end
supports_scrubbing() click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 101
def supports_scrubbing
  true
end
unstore(token) click to toggle source

Unstore a customer and associated credit card.

# File lib/active_merchant/billing/gateways/pin.rb, line 51
def unstore(token)
  customer_token =
    if /cus_/.match?(token)
      get_customer_token(token)
    else
      token
    end
  commit(:delete, "customers/#{CGI.escape(customer_token)}", {}, {})
end
update(token, creditcard, options = {}) click to toggle source

Updates the credit card for the customer.

# File lib/active_merchant/billing/gateways/pin.rb, line 91
def update(token, creditcard, options = {})
  post = {}
  token = get_customer_token(token)

  add_creditcard(post, creditcard)
  add_customer_data(post, options)
  add_address(post, creditcard, options)
  commit(:put, "customers/#{CGI.escape(token)}", post, options)
end
verify_3ds(session_token, options = {}) click to toggle source

Verify a previously authorized charge.

# File lib/active_merchant/billing/gateways/pin.rb, line 86
def verify_3ds(session_token, options = {})
  commit(:get, "/charges/verify?session_token=#{session_token}", nil, options)
end
void(token, options = {}) click to toggle source

Voids a previously authorized charge.

# File lib/active_merchant/billing/gateways/pin.rb, line 81
def void(token, options = {})
  commit(:put, "charges/#{CGI.escape(token)}/void", {}, options)
end

Private Instance Methods

add_3ds(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 188
def add_3ds(post, options)
  if options[:three_d_secure]
    post[:three_d_secure] = {}
    if options[:three_d_secure][:enabled]
      post[:three_d_secure][:enabled] = true
      post[:three_d_secure][:fallback_ok] = options[:three_d_secure][:fallback_ok] unless options[:three_d_secure][:fallback_ok].nil?
      post[:three_d_secure][:callback_url] = options[:three_d_secure][:callback_url] if options[:three_d_secure][:callback_url]
    else
      post[:three_d_secure][:version] = options[:three_d_secure][:version] if options[:three_d_secure][:version]
      post[:three_d_secure][:eci] = options[:three_d_secure][:eci] if options[:three_d_secure][:eci]
      post[:three_d_secure][:cavv] = options[:three_d_secure][:cavv] if options[:three_d_secure][:cavv]
      post[:three_d_secure][:transaction_id] = options[:three_d_secure][:ds_transaction_id] || options[:three_d_secure][:xid]
    end
  end
end
add_address(post, creditcard, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 125
def add_address(post, creditcard, options)
  return if creditcard.kind_of?(String)

  address = (options[:billing_address] || options[:address])
  return unless address

  post[:card] ||= {}
  post[:card].merge!(
    address_line1: address[:address1],
    address_city: address[:city],
    address_postcode: address[:zip],
    address_state: address[:state],
    address_country: address[:country]
  )
end
add_amount(post, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 114
def add_amount(post, money, options)
  post[:amount] = amount(money)
  post[:currency] = (options[:currency] || currency(money))
  post[:currency] = post[:currency].upcase if post[:currency]
end
add_capture(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 146
def add_capture(post, options)
  capture = options[:capture]

  post[:capture] = capture != false
end
add_creditcard(post, creditcard) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 152
def add_creditcard(post, creditcard)
  if creditcard.respond_to?(:number)
    post[:card] ||= {}

    post[:card].merge!(
      number: creditcard.number,
      expiry_month: creditcard.month,
      expiry_year: creditcard.year,
      cvc: creditcard.verification_value,
      name: creditcard.name
    )
  elsif creditcard.kind_of?(String)
    if /^card_/.match?(creditcard)
      post[:card_token] = get_card_token(creditcard)
    else
      post[:customer_token] = creditcard
    end
  end
end
add_customer_data(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 120
def add_customer_data(post, options)
  post[:email] = options[:email] if options[:email]
  post[:ip_address] = options[:ip] if options[:ip]
end
add_invoice(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 141
def add_invoice(post, options)
  post[:description] = options[:description] || 'Active Merchant Purchase'
  post[:reference] = options[:reference] if options[:reference]
end
add_metadata(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 180
def add_metadata(post, options)
  post[:metadata] = options[:metadata] if options[:metadata]
end
add_platform_adjustment(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 184
def add_platform_adjustment(post, options)
  post[:platform_adjustment] = options[:platform_adjustment] if options[:platform_adjustment]
end
commit(method, action, params, options) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 215
def commit(method, action, params, options)
  url = "#{test? ? test_url : live_url}/#{action}"

  begin
    raw_response = ssl_request(method, url, post_data(params), headers(options))
    body = parse(raw_response)
  rescue ResponseError => e
    body = parse(e.response.body)
  end

  if body.nil?
    no_content_response
  elsif body['response']
    success_response(body)
  elsif body['error']
    error_response(body)
  end
rescue JSON::ParserError
  return unparsable_response(raw_response)
end
error_response(body) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 247
def error_response(body)
  Response.new(
    false,
    body['error_description'],
    body,
    authorization: nil,
    test: test?
  )
end
get_card_token(token) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 176
def get_card_token(token)
  token.split(/;(?=cus)/).first
end
get_customer_token(token) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 172
def get_customer_token(token)
  token.split(/;(?=cus)/).last
end
headers(params = {}) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 204
def headers(params = {})
  result = {
    'Content-Type' => 'application/json',
    'Authorization' => "Basic #{Base64.strict_encode64(options[:api_key] + ':').strip}"
  }

  result['X-Partner-Key'] = params[:partner_key] if params[:partner_key]
  result['X-Safe-Card'] = params[:safe_card] if params[:safe_card]
  result
end
no_content_response() click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 257
def no_content_response
  Response.new(
    true,
    nil,
    {},
    test: test?
  )
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 280
def parse(body)
  JSON.parse(body) unless body.nil? || body.length == 0
end
post_data(parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 284
def post_data(parameters = {})
  return nil unless parameters

  parameters.to_json
end
success_response(body) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 236
def success_response(body)
  response = body['response']
  Response.new(
    true,
    response['status_message'],
    body,
    authorization: token(response),
    test: test?
  )
end
token(response) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 272
def token(response)
  if response['token'].start_with?('cus')
    "#{response.dig('card', 'token')};#{response['token']}"
  else
    response['token']
  end
end
unparsable_response(raw_response) click to toggle source
# File lib/active_merchant/billing/gateways/pin.rb, line 266
def unparsable_response(raw_response)
  message = 'Invalid JSON response received from Pin Payments. Please contact support@pinpayments.com if you continue to receive this message.'
  message += " (The raw response returned by the API was #{raw_response.inspect})"
  return Response.new(false, message)
end