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
8 changed files
with
525 additions
and
0 deletions.
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,55 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module Citrus | ||
autoload :Helper, File.dirname(__FILE__) + '/citrus/helper.rb' | ||
autoload :Notification, File.dirname(__FILE__) + '/citrus/notification.rb' | ||
autoload :Return, File.dirname(__FILE__) + '/citrus/return.rb' | ||
|
||
mattr_accessor :sandbox_url | ||
mattr_accessor :staging_url | ||
mattr_accessor :production_url | ||
mattr_accessor :pmt_url | ||
|
||
|
||
self.sandbox_url = 'https://sandbox.citruspay.com/' | ||
self.staging_url = 'https://stg.citruspay.com/' | ||
self.production_url = 'https://www.citruspay.com/' | ||
|
||
|
||
def self.service_url | ||
mode = ActiveMerchant::Billing::Base.integration_mode | ||
case mode | ||
when :production | ||
self.production_url + self.pmt_url | ||
when :test | ||
self.sandbox_url + self.pmt_url | ||
when :staging | ||
self.staging_url + self.pmt_url | ||
else | ||
raise StandardError, "Integration mode set to an invalid value: #{mode}" | ||
end | ||
end | ||
|
||
def self.helper(order, account, options = {}) | ||
Helper.new(order, account, options) | ||
end | ||
|
||
def self.notification(post, options = {}) | ||
Notification.new(post) | ||
end | ||
|
||
def self.return(query_string, options = {}) | ||
Return.new(query_string) | ||
end | ||
|
||
def self.checksum(secret_key, payload_items ) | ||
digest = OpenSSL::Digest::Digest.new('sha1') | ||
sig=OpenSSL::HMAC.hexdigest(digest, secret_key, payload_items) | ||
return sig | ||
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 |
---|---|---|
@@ -0,0 +1,42 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module Citrus | ||
class Helper < ActiveMerchant::Billing::Integrations::Helper | ||
|
||
mapping :order, 'merchantTxnId' | ||
mapping :amount, 'orderAmount' | ||
mapping :account, 'merchantAccessKey' | ||
mapping :credential2, 'secret_key' | ||
mapping :credential3, 'pmt_url' | ||
mapping :currency, 'currency' | ||
|
||
mapping :customer, :first_name => 'firstName',:last_name => 'lastName', :email => 'email', :phone => 'mobileNo' | ||
|
||
mapping :billing_address, :city => 'addressCity', :address1 => 'addressStreet1', :address2 => 'addressStreet2',:state => 'addressState',:zip => 'addressZip', :country => 'addressCountry' | ||
|
||
mapping :checksum, 'secSignature' | ||
mapping :return_url, 'returnUrl' | ||
|
||
|
||
def initialize(order, account, options = {}) | ||
super | ||
add_field 'paymentMode', 'NET_BANKING' | ||
add_field 'reqtime', (Time.now.to_i * 1000).to_s | ||
end | ||
|
||
def form_fields | ||
@fields.merge(mappings[:checksum] => generate_checksum) | ||
end | ||
|
||
def generate_checksum() | ||
checksum_fields = @fields["pmt_url"] + @fields["orderAmount"].to_s + @fields["merchantTxnId"] + @fields["currency"] | ||
Citrus.checksum(@fields["secret_key"], checksum_fields ) | ||
end | ||
|
||
end | ||
|
||
end | ||
end | ||
end | ||
end |
145 changes: 145 additions & 0 deletions
145
lib/active_merchant/billing/integrations/citrus/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,145 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module Citrus | ||
class Notification < ActiveMerchant::Billing::Integrations::Notification | ||
|
||
def initialize(post, options = {}) | ||
super(post, options) | ||
@secret_key = options[:credential2] | ||
end | ||
|
||
def complete? | ||
status == "success" || status == 'canceled' | ||
end | ||
|
||
# Status of the transaction. List of possible values: | ||
# <tt>invalid</tt>:: transaction id is not present | ||
# <tt>tampered</tt>:: transaction data has been tampered | ||
# <tt>success</tt>:: transaction successful | ||
# <tt>canceled</tt>:: transaction is pending for some approval | ||
def status | ||
@status ||= if checksum_ok? | ||
if transaction_id.blank? | ||
'invalid' | ||
else | ||
transaction_status.downcase | ||
end | ||
else | ||
'tampered' | ||
end | ||
end | ||
|
||
def invoice_ok?( order_id ) | ||
order_id.to_s == invoice.to_s | ||
end | ||
|
||
# Order amount should be equal to gross - discount | ||
def amount_ok?( order_amount ) | ||
BigDecimal.new( amount ) == order_amount | ||
end | ||
|
||
# capture Citrus response parameters | ||
|
||
# This is the invoice which you passed to Citrus | ||
def invoice | ||
params['TxId'] | ||
end | ||
|
||
# Status of transaction return from the Citrus. List of possible values: | ||
# <tt>SUCCESS</tt>:: | ||
# <tt>CANCELED</tt>:: | ||
def transaction_status | ||
params['TxStatus'] | ||
end | ||
|
||
# amount paid by customer | ||
def amount | ||
params['amount'] | ||
end | ||
|
||
# ID of this transaction returned by Citrus | ||
def transaction_id | ||
params['pgTxnNo'] | ||
end | ||
|
||
# for future use | ||
def issuerrefno | ||
params['issuerRefNo'] | ||
end | ||
|
||
# authorization code by Citrus | ||
def authidcode | ||
params['authIdCode'] | ||
end | ||
|
||
# gateway resp code by Citrus | ||
def pgrespcode | ||
params['pgRespCode'] | ||
end | ||
|
||
# by Citrus | ||
def checksum | ||
params['signature'] | ||
end | ||
|
||
def paymentmode | ||
params['paymentMode'] | ||
end | ||
|
||
# payment currency | ||
def currency | ||
params['currency'] | ||
end | ||
|
||
|
||
# Email of the customer | ||
def customer_email | ||
params['email'] | ||
end | ||
|
||
# Phone of the customer | ||
def customer_phone | ||
params['mobileNo'] | ||
end | ||
|
||
# Firstname of the customer | ||
def customer_first_name | ||
params['firstName'] | ||
end | ||
|
||
# Lastname of the customer | ||
def customer_last_name | ||
params['lastName'] | ||
end | ||
|
||
# Full address of the customer | ||
def customer_address | ||
{ :address1 => params['addressStreet1'], :address2 => params['addressStreet2'], | ||
:city => params['addressCity'], :state => params['addressState'], | ||
:country => params['addressCountry'], :zip => params['addressZip'] } | ||
end | ||
|
||
|
||
def message | ||
@message || params['TxMsg'] | ||
end | ||
|
||
def acknowledge | ||
checksum_ok? | ||
end | ||
|
||
def checksum_ok? | ||
fields = invoice + transaction_status + amount.to_s + transaction_id + issuerrefno + authidcode + customer_first_name + customer_last_name + pgrespcode + customer_address[:zip] | ||
|
||
unless Citrus.checksum(@secret_key, fields ) == checksum | ||
@message = 'checksum mismatch...' | ||
return false | ||
end | ||
true | ||
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 |
---|---|---|
@@ -0,0 +1,40 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
module Integrations #:nodoc: | ||
module Citrus | ||
class Return < ActiveMerchant::Billing::Integrations::Return | ||
|
||
def initialize(query_string, options = {}) | ||
super | ||
@notification = Notification.new(query_string, options) | ||
end | ||
|
||
# Citrus Transaction Id | ||
# | ||
def transaction_id | ||
@notification.transaction_id | ||
end | ||
|
||
def status( order_id, order_amount ) | ||
if @notification.invoice_ok?( order_id ) && @notification.amount_ok?( BigDecimal.new(order_amount) ) | ||
@notification.status | ||
else | ||
'mismatch' | ||
end | ||
end | ||
|
||
# check success of the transaction | ||
# check order_id and | ||
def success? | ||
status( @params['TxId'], @params['amount'] ) == 'success' | ||
end | ||
|
||
def message | ||
@notification.message | ||
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 |
---|---|---|
@@ -0,0 +1,44 @@ | ||
require 'test_helper' | ||
|
||
class CitrusModuleTest < Test::Unit::TestCase | ||
include ActiveMerchant::Billing::Integrations | ||
|
||
def setup | ||
ActiveMerchant::Billing::Base.integration_mode = :test | ||
@access_key = 'G0JW45KCS3630NX335YX' | ||
@secret_key = '2c71a4ea7d2b88e151e60d9da38b2d4552568ba9' | ||
@pmt_url = 'gqwnliur74' | ||
end | ||
|
||
def test_service_url_method | ||
Citrus.pmt_url=@pmt_url | ||
ActiveMerchant::Billing::Base.integration_mode = :test | ||
assert_equal 'https://sandbox.citruspay.com/gqwnliur74', Citrus.service_url | ||
p Citrus.service_url | ||
end | ||
|
||
def test_production_service_url_method | ||
Citrus.pmt_url=@pmt_url | ||
ActiveMerchant::Billing::Base.integration_mode = :production | ||
assert_equal 'https://www.citruspay.com/gqwnliur74', Citrus.service_url | ||
p Citrus.service_url | ||
end | ||
|
||
def test_helper_method | ||
assert_instance_of Citrus::Helper, Citrus.helper('ORD01','G0JW45KCS3630NX335YX', :amount => 10.0, :currency => 'USD', :credential2 => '2c71a4ea7d2b88e151e60d9da38b2d4552568ba9', :credential3 => 'gqwnliur74') | ||
end | ||
|
||
def test_return_method | ||
assert_instance_of Citrus::Return, Citrus.return('name=foo', {}) | ||
end | ||
|
||
def test_notification_method | ||
assert_instance_of Citrus::Notification, Citrus.notification('name=cody') | ||
end | ||
|
||
def test_checksum_method | ||
payu_load = @pmt_url+"10"+"ORD123"+"USD" | ||
assert_equal "ecf7eaafec270b9b91b898e7f8e794c30245eb7f", Citrus.checksum(@secret_key, payu_load) | ||
end | ||
|
||
end |
Oops, something went wrong.