Advertisement
Guest User

Untitled

a guest
Apr 20th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 4.52 KB | None | 0 0
  1. #encoding: utf-8
  2. #
  3. # Implementation of the Bambora PayForm née Paybyway API, including
  4. # payment token requests, credit card charge requests & verifications,
  5. # and bank e-payments.
  6. # For API docs, see
  7. # <https://payform.bambora.com/docs/web_payments/?page=full-api-reference>
  8.  
  9. module PaymentGateway
  10.  
  11.   class PaybywayConnector
  12.     include HTTParty
  13.     base_uri 'https://payform.bambora.com/pbwapi/'
  14.     headers 'Content-Type' => 'application/json'
  15.     format :json
  16.     logger Rails.logger
  17.  
  18.     def auth_payment(token_request)
  19.       self.class.post('/auth_payment', body: token_request.to_json)
  20.     end
  21.  
  22.     def check_payment_status(verify_request)
  23.       self.class.post('/check_payment_status', body: verify_request.to_json)
  24.     end
  25.  
  26.     def charge_url
  27.       "#{self.class.base_uri}/charge"
  28.     end
  29.  
  30.     def token_url(token)
  31.       "#{self.class.base_uri}/token/#{token}"
  32.     end
  33.   end
  34.  
  35.   class Paybyway
  36.  
  37.     include ActiveModel::Model
  38.  
  39.     attr_accessor :order, :return_url, :notify_url
  40.  
  41.     def initialize(attributes = {})
  42.       super
  43.       raise ArgumentError if order.nil?
  44.       @api_key = order.store.pbw_api_key
  45.       @private_key = order.store.pbw_private_key
  46.       @version = 'w3.1'
  47.       @connector = PaybywayConnector.new
  48.     end
  49.  
  50.     #
  51.     # The methods below create charge requests and return JSON responses.
  52.     #
  53.     def charge_credit_card(params = {})
  54.       request = token_request(payment_method: {
  55.         type: 'card', register_card_token: 0
  56.       })
  57.       response = @connector.auth_payment(request).parsed_response
  58.       {
  59.         result: response['result'],
  60.         token: response['token'],
  61.         amount: request[:amount],
  62.         currency: request[:currency],
  63.         payment_url: @connector.charge_url
  64.       }
  65.     end
  66.  
  67.     def charge_e_payment(params = {})
  68.       request = token_request(payment_method: {
  69.         type: 'e-payment',
  70.         return_url: return_url,
  71.         notify_url: notify_url,
  72.         lang: 'fi',
  73.         token_valid_until: (Time.current + 6.hours).to_i,
  74.         selected: [params[:selected]]
  75.       })
  76.       response = @connector.auth_payment(request).parsed_response
  77.       {
  78.         payment_url: @connector.token_url(response['token'])
  79.       }
  80.     end
  81.  
  82.     # Sends a payment status request.
  83.     def verify(token)
  84.       request = verify_request(token)
  85.       response = @connector.check_payment_status(request).parsed_response
  86.       response['result'] == 0
  87.     end
  88.  
  89.     # Checks the return params from a bank e-payment.
  90.     # Returns the unique order number if successful, nil otherwise.
  91.     def return(params)
  92.       return_code  = params['RETURN_CODE']
  93.       order_number = params['ORDER_NUMBER']
  94.       settled      = params['SETTLED']
  95.       contact_id   = params['CONTACT_ID']
  96.       incident_id  = params['INCIDENT_ID']
  97.       authcode     = params['AUTHCODE']
  98.       return nil unless return_code == '0'
  99.       if return_code.present? && order_number.present? && authcode.present?
  100.         cleartext = [return_code, order_number, settled, contact_id, incident_id].compact.join('|')
  101.         if authcode == sha256(@private_key, cleartext)
  102.           return order_number
  103.         end
  104.       end
  105.       nil
  106.     end
  107.  
  108.     # Orders using this payment gateway can't be confirmed
  109.     # without collecting a payment.
  110.     def confirm
  111.       false
  112.     end
  113.  
  114.     def to_partial_path
  115.       'payment_gateway/paybyway'
  116.     end
  117.  
  118.     private
  119.  
  120.       def token_request(options = {})
  121.         number = SecureRandom.hex(12)
  122.         first, last = order.customer_name.split(/\s+/, 2)
  123.         street, zip, city = order.billing_address_components
  124.         {
  125.           version: @version,
  126.           api_key: @api_key,
  127.           order_number: number,
  128.           amount: order.grand_total_with_tax.cents,
  129.           currency: order.grand_total_with_tax.currency_as_string,
  130.           email: order.customer_email,
  131.           authcode: sha256(@private_key, "#{@api_key}|#{number}"),
  132.           customer: {
  133.             firstname: first,
  134.             lastname: last,
  135.             email: order.customer_email,
  136.             address_street: street,
  137.             address_zip: zip,
  138.             address_city: city
  139.           }
  140.         }.merge(options)
  141.       end
  142.  
  143.       def verify_request(token)
  144.         {
  145.           version: @version,
  146.           api_key: @api_key,
  147.           token: token,
  148.           authcode: sha256(@private_key, "#{@api_key}|#{token}")
  149.         }
  150.       end
  151.  
  152.       def sha256(secret, data)
  153.         OpenSSL::HMAC.hexdigest('sha256', secret, data).upcase
  154.       end
  155.   end
  156. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement