forked from activemerchant/active_merchant
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
766 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module DirecPay | ||
autoload :Helper, File.dirname(__FILE__) + '/direc_pay/helper.rb' | ||
autoload :Return, File.dirname(__FILE__) + '/direc_pay/return.rb' | ||
autoload :Notification, File.dirname(__FILE__) + '/direc_pay/notification.rb' | ||
autoload :Status, File.dirname(__FILE__) + '/direc_pay/status.rb' | ||
|
||
mattr_accessor :production_url, :test_url | ||
|
||
self.production_url = "https://www.timesofmoney.com/direcpay/secure/dpMerchantTransaction.jsp" | ||
self.test_url = "https://test.timesofmoney.com/direcpay/secure/dpMerchantTransaction.jsp" | ||
|
||
def self.service_url | ||
mode = ActiveMerchant::Billing::Base.integration_mode | ||
case mode | ||
when :production | ||
self.production_url | ||
when :test | ||
self.test_url | ||
else | ||
raise StandardError, "Integration mode set to an invalid value: #{mode}" | ||
end | ||
end | ||
|
||
def self.notification(post) | ||
Notification.new(post) | ||
end | ||
|
||
def self.return(query_string) | ||
Return.new(query_string) | ||
end | ||
end | ||
end | ||
end | ||
end |
188 changes: 188 additions & 0 deletions
188
lib/active_merchant/billing/integrations/direc_pay/helper.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module DirecPay | ||
class Helper < ActiveMerchant::Billing::Integrations::Helper | ||
mapping :account, 'MID' | ||
mapping :order, 'Merchant Order No' | ||
mapping :amount, 'Amount' | ||
mapping :currency, 'Currency' | ||
mapping :country, 'Country' | ||
|
||
mapping :billing_address, :city => 'custCity', | ||
:address1 => 'custAddress', | ||
:state => 'custState', | ||
:zip => 'custPinCode', | ||
:country => 'custCountry', | ||
:phone2 => 'custMobileNo' | ||
|
||
mapping :shipping_address, :name => 'deliveryName', | ||
:city => 'deliveryCity', | ||
:address1 => 'deliveryAddress', | ||
:state => 'deliveryState', | ||
:zip => 'deliveryPinCode', | ||
:country => 'deliveryCountry', | ||
:phone2 => 'deliveryMobileNo' | ||
|
||
mapping :customer, :name => 'custName', | ||
:email => 'custEmailId' | ||
|
||
mapping :description, 'otherNotes' | ||
mapping :edit_allowed, 'editAllowed' | ||
|
||
mapping :return_url, 'Success URL' | ||
mapping :failure_url, 'Failure URL' | ||
|
||
mapping :operating_mode, 'Operating Mode' | ||
mapping :other_details, 'Other Details' | ||
mapping :collaborator, 'Collaborator' | ||
|
||
OPERATING_MODE = 'DOM' | ||
COUNTRY = 'IND' | ||
CURRENCY = 'INR' | ||
OTHER_DETAILS = 'NULL' | ||
EDIT_ALLOWED = 'N' | ||
|
||
PHONE_CODES = { | ||
'IN' => '91', | ||
'US' => '01', | ||
'CA' => '01' | ||
} | ||
|
||
ENCODED_PARAMS = [ :account, :operating_mode, :country, :currency, :amount, :order, :other_details, :return_url, :failure_url, :collaborator ] | ||
|
||
|
||
def initialize(order, account, options = {}) | ||
super | ||
collaborator = ActiveMerchant::Billing::Base.integration_mode == :test || options[:test] ? 'TOML' : 'DirecPay' | ||
add_field(mappings[:collaborator], collaborator) | ||
add_field(mappings[:country], 'IND') | ||
add_field(mappings[:operating_mode], OPERATING_MODE) | ||
add_field(mappings[:other_details], OTHER_DETAILS) | ||
add_field(mappings[:edit_allowed], EDIT_ALLOWED) | ||
end | ||
|
||
|
||
def customer(params = {}) | ||
full_name = "#{params[:first_name]} #{params[:last_name]}" | ||
add_field(mappings[:customer][:name], full_name) | ||
add_field(mappings[:customer][:email], params[:email]) | ||
end | ||
|
||
# Need to format the amount to have 2 decimal places | ||
def amount=(money) | ||
cents = money.respond_to?(:cents) ? money.cents : money | ||
if money.is_a?(String) or cents.to_i <= 0 | ||
raise ArgumentError, 'money amount must be either a Money object or a positive integer in cents.' | ||
end | ||
add_field(mappings[:amount], sprintf("%.2f", cents.to_f/100)) | ||
end | ||
|
||
def shipping_address(params = {}) | ||
add_street_address!(params) | ||
super(params.dup) | ||
add_field(mappings[:shipping_address][:name], fields[mappings[:customer][:name]]) if fields[mappings[:shipping_address][:name]].blank? | ||
add_phone_for!(:shipping_address, params) | ||
end | ||
|
||
def billing_address(params = {}) | ||
add_street_address!(params) | ||
super(params.dup) | ||
add_phone_for!(:billing_address, params) | ||
end | ||
|
||
def form_fields | ||
add_failure_url | ||
add_request_parameters | ||
|
||
unencoded_parameters | ||
end | ||
|
||
|
||
private | ||
|
||
def add_request_parameters | ||
params = ENCODED_PARAMS.map{ |param| fields[mappings[param]] } | ||
encoded = encode_value(params.join('|')) | ||
|
||
add_field('requestparameter', encoded) | ||
end | ||
|
||
def unencoded_parameters | ||
params = fields.dup | ||
# remove all encoded params from exported fields | ||
ENCODED_PARAMS.each{ |param| params.delete(mappings[param]) } | ||
# remove all special characters from each field value | ||
params = params.collect{|name, value| [name, remove_special_characters(value)] } | ||
Hash[params] | ||
end | ||
|
||
def add_failure_url | ||
if fields[mappings[:failure_url]].nil? | ||
add_field(mappings[:failure_url], fields[mappings[:return_url]]) | ||
end | ||
end | ||
|
||
def add_street_address!(params) | ||
address = params[:address1] | ||
address << " #{params[:address2]}" if params[:address2] | ||
params.merge!(:address1 => address) | ||
end | ||
|
||
def add_phone_for!(address_type, params) | ||
address_field = address_type == :billing_address ? 'custPhoneNo' : 'deliveryPhNo' | ||
|
||
if params.has_key?(:phone) | ||
country = fields[mappings[address_type][:country]] | ||
phone = params[:phone].to_s | ||
# Remove all non digits | ||
phone.gsub!(/[^\d ]+/, '') | ||
|
||
phone_country_code, phone_area_code, phone_number = nil | ||
|
||
if country == 'IN' && phone =~ /(91)? *(\d{3}) *(\d{4,})$/ | ||
phone_country_code, phone_area_code, phone_number = $1, $2, $3 | ||
else | ||
numbers = phone.split(' ') | ||
case numbers.size | ||
when 3 | ||
phone_country_code, phone_area_code, phone_number = numbers | ||
when 2 | ||
phone_area_code, phone_number = numbers | ||
else | ||
phone =~ /(\d{3})(\d+)$/ | ||
phone_area_code, phone_number = $1, $2 | ||
end | ||
end | ||
|
||
add_field("#{address_field}1", phone_country_code || phone_code_for_country(country) || '91') | ||
add_field("#{address_field}2", phone_area_code) | ||
add_field("#{address_field}3", phone_number) | ||
end | ||
end | ||
|
||
# Special characters are NOT allowed while posting transaction parameters on DirecPay system | ||
def remove_special_characters(string) | ||
string.gsub(/[~"'&#%]/, '-') | ||
end | ||
|
||
def encode_value(value) | ||
encoded = ActiveSupport::Base64.encode64s(value) | ||
string_to_encode = encoded[0, 1] + "T" + encoded[1, encoded.length] | ||
ActiveSupport::Base64.encode64s(string_to_encode) | ||
end | ||
|
||
def decode_value(value) | ||
decoded = ActiveSupport::Base64.decode64(value) | ||
string_to_decode = decoded[0, 1] + decoded[2, decoded.length] | ||
ActiveSupport::Base64.decode64(string_to_decode) | ||
end | ||
|
||
def phone_code_for_country(country) | ||
PHONE_CODES[country] | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
76 changes: 76 additions & 0 deletions
76
lib/active_merchant/billing/integrations/direc_pay/notification.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
require 'net/http' | ||
|
||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module DirecPay | ||
class Notification < ActiveMerchant::Billing::Integrations::Notification | ||
RESPONSE_PARAMS = ['DirecPay Reference ID', 'Flag', 'Country', 'Currency', 'Other Details', 'Merchant Order No', 'Amount'] | ||
|
||
def acknowledge | ||
true | ||
end | ||
|
||
def complete? | ||
status == 'Completed' || status == 'Pending' | ||
end | ||
|
||
def status | ||
case params['Flag'] | ||
when 'SUCCESS' | ||
'Completed' | ||
when 'PENDING' | ||
'Pending' | ||
when 'FAIL' | ||
'Failed' | ||
else | ||
'Error' | ||
end | ||
end | ||
|
||
def item_id | ||
params['Merchant Order No'] | ||
end | ||
|
||
def transaction_id | ||
params['DirecPay Reference ID'] | ||
end | ||
|
||
# the money amount we received in X.2 decimal | ||
def gross | ||
params['Amount'] | ||
end | ||
|
||
def currency | ||
params['Currency'] | ||
end | ||
|
||
def country | ||
params['Country'] | ||
end | ||
|
||
def other_details | ||
params['Other Details'] | ||
end | ||
|
||
def test? | ||
false | ||
end | ||
|
||
# Take the posted data and move the relevant data into a hash | ||
def parse(post) | ||
super | ||
|
||
values = params['responseparams'].to_s.split('|') | ||
response_params = values.size == 3 ? ['DirecPay Reference ID', 'Flag', 'Error message'] : RESPONSE_PARAMS | ||
response_params.each_with_index do |name, index| | ||
params[name] = values[index] | ||
end | ||
params | ||
end | ||
|
||
end | ||
end | ||
end | ||
end | ||
end |
32 changes: 32 additions & 0 deletions
32
lib/active_merchant/billing/integrations/direc_pay/return.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
|
||
module DirecPay | ||
class Return < ActiveMerchant::Billing::Integrations::Return | ||
|
||
def initialize(post_data, options = {}) | ||
@notification = Notification.new(treat_failure_as_pending(post_data), options) | ||
end | ||
|
||
def success? | ||
notification.complete? | ||
end | ||
|
||
def message | ||
notification.status | ||
end | ||
|
||
|
||
private | ||
|
||
# Work around the issue that the initial return from DirecPay is always either SUCCESS or FAIL, there is no PENDING | ||
def treat_failure_as_pending(post_data) | ||
post_data.sub(/FAIL/, 'PENDING') | ||
end | ||
end | ||
end | ||
|
||
end | ||
end | ||
end |
37 changes: 37 additions & 0 deletions
37
lib/active_merchant/billing/integrations/direc_pay/status.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module DirecPay | ||
|
||
class Status | ||
include PostsData | ||
|
||
STATUS_TEST_URL = 'https://test.timesofmoney.com/direcpay/secure/dpPullMerchAtrnDtls.jsp' | ||
STATUS_LIVE_URL = 'https://www.timesofmoney.com/direcpay/secure/dpPullMerchAtrnDtls.jsp' | ||
|
||
attr_reader :account, :options | ||
|
||
def initialize(account, options = {}) | ||
@account, @options = account, options | ||
end | ||
|
||
|
||
# Use this method to manually request a status update to the provided notification_url | ||
def update(authorization, notification_url) | ||
url = test? ? STATUS_TEST_URL : STATUS_LIVE_URL | ||
parameters = [ authorization, account, notification_url ] | ||
data = PostData.new | ||
data[:requestparams] = parameters.join('|') | ||
|
||
response = ssl_get("#{url}?#{data.to_post_data}") | ||
end | ||
|
||
def test? | ||
ActiveMerchant::Billing::Base.integration_mode == :test || options[:test] | ||
end | ||
|
||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -383,4 +383,5 @@ garanti: | |
login: 'paymentuser' | ||
password: 'userpayment' | ||
|
||
|
||
direc_pay: | ||
mid: 200904281000001 |
Oops, something went wrong.