Last active
October 25, 2016 17:41
-
-
Save itskingori/51be3c543dcba43a3a77 to your computer and use it in GitHub Desktop.
Controller example on how to use Pesapal gem ...
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
module Account | |
module Payments | |
class PesapalController < ApplicationController | |
# GET /account/payments/pesapal/new | |
def new | |
# Configure transaction details | |
pesapal = Pesapal::Merchant.new | |
pesapal.order_details = { | |
amount: '<AMOUNT>', | |
description: '<DESCRIPTION>', | |
type: 'MERCHANT', | |
reference: '<REFERENCE>', | |
first_name:'<FIRST_NAME>', | |
last_name: '<LAST_NAME>', | |
email: '<EMAIL>', | |
phonenumber: '<PHONE_NUMBER>', | |
currency: 'KES_or_USD' | |
} | |
# Configure API settings while passing on the data that we need | |
pesapal.config = { | |
callback_url: pesapal_callback_account_payments_url, | |
consumer_key: Rails.application.secrets.pesapal_consumer_key, | |
consumer_secret: Rails.application.secrets.pesapal_consumer_secret | |
} | |
# Generate iframe | |
@order_url = pesapal.generate_order_url | |
end | |
# GET /account/payments/pesapal/callback | |
def callback | |
payment = Payment.new( | |
user: current_user, | |
reference_no: params.require(:pesapal_merchant_reference), | |
tracking_no: params.require(:pesapal_transaction_tracking_id), | |
amount: "amount", | |
currency_iso_code: "currency.iso_code", | |
status: 'pending' | |
) | |
if payment.save | |
redirect_to account_payments_url, notice: "Your payment of XXX has been completed but is still pending confirmation." | |
return | |
end | |
redirect_to new_account_payment_url, alert: "Your payment of XXX was not completed successfully." | |
end | |
# GET /account/payments/pesapal/ipn | |
def ipn | |
# Initialize Pesapal | |
pesapal = Pesapal::Merchant.new | |
pesapal.config = { | |
consumer_key: Rails.application.secrets.pesapal_consumer_key, | |
consumer_secret: Rails.application.secrets.pesapal_consumer_secret | |
} | |
# Get the pesapal transaction identifiers | |
reference_no = params.require(:pesapal_merchant_reference) | |
tracking_no = params.require(:pesapal_transaction_tracking_id) | |
# Make sure we respond to Pesapal and also, depending on the data from | |
# Pesapal ... apply our business logic appropriately. | |
respond_to do |format| | |
# Do nothing if we don't have what we need | |
if reference_no.blank? || tracking_no.blank? | |
format.html { render nothing: true } | |
# ... else apply business login ... | |
else | |
# Get hash with response from the `ipn_listener` helper | |
# method: | |
# | |
# { | |
# status: "<PAYMENT_STATUS>", | |
# response: "<IPN_RESPONSE>" | |
# } | |
ipn_response = pesapal.ipn_listener 'CHANGE', reference_no, tracking_no | |
# If payment exists in the DB so we proceed with updating it's | |
# status. INVALID indicates that the transaction with the reference | |
# you provided could not be found. | |
payment = ::Payment.find_by reference_no: reference_no, tracking_no: tracking_no | |
apply_ipn_update payment, ipn_response[:status] if payment | |
format.html { render text: ipn_response[:response] } | |
end | |
end | |
end | |
private | |
# Apply the update to the payment depending on the response | |
def apply_ipn_update(payment, ipn_status) | |
case ipn_status | |
when 'COMPLETED' | |
# do something | |
when 'FAILED' | |
# do something | |
when 'PENDING' | |
# do something | |
when 'INVALID' | |
# do somethimg | |
end | |
end | |
# Never trust parameters from the scary internet, only allow the white list through. | |
def payment_params | |
if params.key? :payment | |
params[:payment][:reference_no] = params[:pesapal_merchant_reference] unless params[:pesapal_merchant_reference].blank? | |
params[:payment][:tracking_no] = params[:pesapal_transaction_tracking_id] unless params[:pesapal_transaction_tracking_id].blank? | |
end | |
params.require(:payment).permit(:amount, :currency_iso_code, :payable_type, :reference_no, :tracking_no) | |
end | |
end | |
end | |
end |
@Alfred-W Turns out the issue was already raised and someone had filed a PR! ๐
Pole sana.
@Alfred-W Your issue has been fixed in v1.7.0. There's also v1.8.0 which addresses an important security concern.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Alfred-W I see! I used the sandbox a long time ago so wouldn't have caught that change. All my stuff is in production. Do you mind filing this as an issue? I can update the gem when I get time.
I also think that setting
http.verify_mode
toOpenSSL::SSL::VERIFY_NONE
is a bad idea because we pretty much disregard the SSL certificate! ๐ ... and I don't quite remember why I did this.