Make authenticated Pesapal API calls without the fuss! Easily post an order, query payment status and fetch payment details.
Basically it’s a gem that makes it easy to integrate your app with Pesapal’s payment gateway. It Handles all the oAuth stuff abstracting any direct interaction with the API endpoints so that you can focus on what matters. Building awesome.
All this with no 3rd party oAuth library dependencies, it handles all the oAuth flows on its own so your app is one dependency less.
The gem should be up on RubyGems.org, it’s accompanying API reference here, the CHANGELOG here and all the releases here.
Ps: This documentation is based off v2.0.0
. For older versions, rely on the
version specific documentation. You can find the link on RubyGems.org.
Add this line to your application’s Gemfile:
gem 'pesapal'
And then execute:
$ bundle
Or install it yourself as:
$ gem install pesapal
Initialize Pesapal object and choose the environment, there are two environments;
:development
and :production
. They determine if the code will interact
with the testing or the live Pesapal API.
# Sets environment to :development
pesapal = Pesapal::Merchant.new(:development)
# Sets environment to :production
pesapal = Pesapal::Merchant.new(:production)
Use a hash as shown below (please note that Pesapal provides different keys for different environments, make sure you choose the right one).
pesapal.config = {
callback_url: 'http://0.0.0.0:3000/pesapal/callback',
consumer_key: '<YOUR_CONSUMER_KEY>',
consumer_secret: '<YOUR_CONSUMER_SECRET>'
}
Once you’ve finalized the configuration, set up the order details in a hash as shown in the example below … all keys MUST be present. If there’s one that you wish to ignore just leave it with a blank string but make sure it’s included e.g. the phonenumber.
pesapal.order_details = {
amount: 1000,
description: 'this is the transaction description',
type: 'MERCHANT',
reference: '808-707-606',
first_name: 'Swaleh',
last_name: 'Mdoe',
email: 'user@example.com',
phonenumber: '+254722222222',
currency: 'KES'
}
Then generate the transaction url as below. In the example, the value is
assigned to the variable order_url
which you can pass on to the templating
system of your choice to generate an iframe. Please note that this method
utilizes all that information set in the previous steps in generating the url so
it’s important that it’s the last step in the post order process.
# generate transaction url
order_url = pesapal.generate_order_url
# order_url will a string with the url example;
# http://demo.pesapal.com/API/PostPesapalDirectOrderV4?oauth_callback=http%3A%2F%2F1.2.3.4%3A3000%2Fpesapal%2Fcallback&oauth_consumer_key=A9MXocJiHK1P4w0M%2F%2FYzxgIVMX557Jt4&oauth_nonce=13804335543pDXs4q3djsy&oauth_signature=BMmLR0AVInfoBI9D4C38YDA9eSM%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1380433554&oauth_version=1.0&pesapal_request_data=%26lt%3B%3Fxml%20version%3D%26quot%3B1.0%26quot%3B%20encoding%3D%26quot%3Butf-8%26quot%3B%3F%26gt%3B%26lt%3BPesapalDirectOrderInfo%20xmlns%3Axsi%3D%26quot%3Bhttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%26quot%3B%20xmlns%3Axsd%3D%26quot%3Bhttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%26quot%3B%20Amount%3D%26quot%3B1000%26quot%3B%20Description%3D%26quot%3Bthis%20is%20the%20transaction%20description%26quot%3B%20Type%3D%26quot%3BMERCHANT%26quot%3B%20Reference%3D%26quot%3B808%26quot%3B%20FirstName%3D%26quot%3BSwaleh%26quot%3B%20LastName%3D%26quot%3BMdoe%26quot%3B%20Email%3D%26quot%3Bj%40kingori.co%26quot%3B%20PhoneNumber%3D%26quot%3B%2B254722222222%26quot%3B%20xmlns%3D%26quot%3Bhttp%3A%2F%2Fwww.pesapal.com%26quot%3B%20%2F%26gt%3B
Ps: Please note the :callback_url
value in the pesapal.config
hash …
after the user successfully posts the order, the response will be sent to this
url. Refer to official Pesapal Step-By-Step integration guide for more
details.
Use this to query the status of the transaction. When a transaction is posted to Pesapal, it may be in a PENDING, COMPLETED, FAILED or INVALID state. If the transaction is PENDING, the payment may complete or fail at a later stage.
Both the unique merchant reference generated by your system (compulsory) and the pesapal transaction tracking id (optional) are input parameters to this method but if you don’t ensure that the merchant reference is unique for each order on your system, you may get INVALID as the response. Because of this, it is recommended that you provide both the merchant reference and transaction tracking id as parameters to guarantee uniqueness.
# option 1: using merchant reference only
payment_status = pesapal.query_payment_status("<MERCHANT_REFERENCE>")
# option 2: using merchant reference and transaction id (recommended)
payment_status = pesapal.query_payment_status("<MERCHANT_REFERENCE>","<TRANSACTION_ID>")
Same as querying payment status above, but the return value contains more information (and is a hash as opposed to a string).
# pass in merchant reference and transaction id
payment_details = pesapal.query_payment_details("<MERCHANT_REFERENCE>","<TRANSACTION_ID>")
The result is a hash that looks something like this …
{
method: "<PAYMENT_METHOD>",
status: "<PAYMENT_STATUS>",
merchant_reference: "<MERCHANT_REFERENCE>",
transaction_tracking_id: "<TRANSACTION_ID>"
}
Use the ipn_listener
method to listen to Pesapal IPN calls to easily create an
appropriate response, example below.
# pass in the notification type, merchant reference and transaction id
response_to_ipn = pesapal.ipn_listener("<NOTIFICATION_TYPE>", "<MERCHANT_REFERENCE>","<TRANSACTION_ID>")
The variable, response_to_ipn
, now holds a response as the one shown below.
Using the status you can customise any actions (e.g. database inserts and
updates) and finally, it’s up to you to send the :response
back to pesapal. The
hard part is done for you.
{
status: "<PAYMENT_STATUS>",
response: "<IPN_RESPONSE>"
}
Ps: Refer to Pesapal official documentation to make sure you understand what data Pesapal sends to IPN and what result they expect back.
In case you are having any issues using this gem please do not email me directly, I’d rather you submit new issues (and even requests) here … obviously after checking if the issue has already been raised and closed. This way, other people get to share in the conversation that would have been private and out of their reach.
Submitting a pull request;
git checkout -b BRANCH_NAME
).rspec spec
.rspec spec
to verify that test fails.git commit -am 'AWESOME COMMIT MESSAGE'
).git push origin BRANCH_NAME
).Gem documentation is of two types, feel free to contribute to any;
Gem home page is built on Jekyll, which is a fun and easy to use static
site generator and hosted on GitHub Pages. The code is in the docs/
folder if you want to have a peek.
Preview the gem API documentation locally by installing Yard (gem install
yard
) and call $ yard server
to set up a local documentation server usually
running on http://0.0.0.0:8808
. The result should be similar to the API
documention up on rubydoc.info/gems/pesapal.
Ps: If you’ve written code and can’t figure out why they aren’t passing (or if you’ve written your own tests … just send a pull a request. We can then do a code review).
Tests run RSpec which is a Behaviour-Driven Development tool. To run tests, call;
$ bundle exec rspec spec
King’ori J. Maina © 2013-2018. The MIT License bundled therein is a permissive license that is short and to the point. It lets people do anything they want as long as they provide attribution and waive liability.