pesapal 1.8.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
 - data/.gitignore +5 -15
 - data/.rubocop.yml +18 -10
 - data/.travis.yml +6 -4
 - data/CHANGELOG.md +12 -1
 - data/LICENSE.md +1 -1
 - data/README.md +10 -15
 - data/docs/.ruby-version +1 -0
 - data/docs/Gemfile +4 -0
 - data/docs/README.md +10 -0
 - data/docs/_config.yml +27 -0
 - data/docs/_includes/google-analytics.html +8 -0
 - data/docs/_layouts/default.html +53 -0
 - data/docs/assets/javascripts/scale.fix.js +17 -0
 - data/docs/assets/stylesheets/pygment_trac.css +69 -0
 - data/docs/assets/stylesheets/styles.css +287 -0
 - data/docs/favicon.ico +0 -0
 - data/docs/index.md +302 -0
 - data/lib/pesapal.rb +0 -2
 - data/lib/pesapal/helper/details.rb +5 -3
 - data/lib/pesapal/helper/post.rb +5 -3
 - data/lib/pesapal/helper/status.rb +8 -7
 - data/lib/pesapal/merchant.rb +55 -141
 - data/lib/pesapal/oauth.rb +13 -11
 - data/lib/pesapal/version.rb +1 -1
 - data/pesapal.gemspec +9 -4
 - data/spec/pesapal_merchant_spec.rb +25 -86
 - metadata +68 -34
 - data/lib/generators/pesapal/install_generator.rb +0 -21
 - data/lib/generators/templates/README.md +0 -21
 - data/lib/generators/templates/pesapal.yml +0 -9
 - data/lib/pesapal/railtie.rb +0 -26
 
    
        data/docs/favicon.ico
    ADDED
    
    | 
         Binary file 
     | 
    
        data/docs/index.md
    ADDED
    
    | 
         @@ -0,0 +1,302 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            title: Get
         
     | 
| 
      
 3 
     | 
    
         
            +
            layout: default
         
     | 
| 
      
 4 
     | 
    
         
            +
            ---
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Synopsis
         
     | 
| 
      
 7 
     | 
    
         
            +
            --------
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            Basically it's a gem that makes it easy to integrate your app with
         
     | 
| 
      
 10 
     | 
    
         
            +
            [Pesapal's][24] payment gateway. It Handles all the [oAuth stuff][1] abstracting
         
     | 
| 
      
 11 
     | 
    
         
            +
            any direct interaction with the API endpoints so that you can focus on what
         
     | 
| 
      
 12 
     | 
    
         
            +
            matters. _Building awesome_.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            All this with no 3rd party oAuth library dependencies, it handles all the oAuth
         
     | 
| 
      
 15 
     | 
    
         
            +
            flows on its own so your app is one dependency less.
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            The gem should be [up on RubyGems.org][7], it's [accompanying API reference
         
     | 
| 
      
 18 
     | 
    
         
            +
            here][13], the [CHANGELOG here][21] and [all the releases here][12].
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            Ps: This documentation is based off `v2.0.0`. For older versions, rely on the
         
     | 
| 
      
 21 
     | 
    
         
            +
            version specific documentation. You can find the link on [RubyGems.org][7].
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            Installation
         
     | 
| 
      
 24 
     | 
    
         
            +
            ------------
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            Add this line to your application's Gemfile:
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                gem 'pesapal'
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            And then execute:
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                $ bundle
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            Or install it yourself as:
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                $ gem install pesapal
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            Usage
         
     | 
| 
      
 39 
     | 
    
         
            +
            -----
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            ### Initialization
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            Initialize Pesapal object and choose the environment, there are two environments;
         
     | 
| 
      
 44 
     | 
    
         
            +
            `:development` and `:production`. They determine if the code will interact
         
     | 
| 
      
 45 
     | 
    
         
            +
            with the testing or the live Pesapal API.
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 48 
     | 
    
         
            +
            # Sets environment to :development
         
     | 
| 
      
 49 
     | 
    
         
            +
            pesapal = Pesapal::Merchant.new(:development)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            # Sets environment to :production
         
     | 
| 
      
 52 
     | 
    
         
            +
            pesapal = Pesapal::Merchant.new(:production)
         
     | 
| 
      
 53 
     | 
    
         
            +
            ```
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            ### Configuration
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            Use a hash as shown below (please note that Pesapal provides different keys for
         
     | 
| 
      
 58 
     | 
    
         
            +
            different environments, make sure you choose the right one).
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 61 
     | 
    
         
            +
            pesapal.config = {
         
     | 
| 
      
 62 
     | 
    
         
            +
              callback_url: 'http://0.0.0.0:3000/pesapal/callback',
         
     | 
| 
      
 63 
     | 
    
         
            +
              consumer_key: '<YOUR_CONSUMER_KEY>',
         
     | 
| 
      
 64 
     | 
    
         
            +
              consumer_secret: '<YOUR_CONSUMER_SECRET>'
         
     | 
| 
      
 65 
     | 
    
         
            +
            }
         
     | 
| 
      
 66 
     | 
    
         
            +
            ```
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            ### Posting An Order
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            Once you've finalized the configuration, set up the order details in a hash as
         
     | 
| 
      
 71 
     | 
    
         
            +
            shown in the example below ... all keys **MUST** be present. If there's one that
         
     | 
| 
      
 72 
     | 
    
         
            +
            you wish to ignore just leave it with a blank string but make sure it's included
         
     | 
| 
      
 73 
     | 
    
         
            +
            e.g. the phonenumber.
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 76 
     | 
    
         
            +
            pesapal.order_details = {
         
     | 
| 
      
 77 
     | 
    
         
            +
              amount: 1000,
         
     | 
| 
      
 78 
     | 
    
         
            +
              description: 'this is the transaction description',
         
     | 
| 
      
 79 
     | 
    
         
            +
              type: 'MERCHANT',
         
     | 
| 
      
 80 
     | 
    
         
            +
              reference: '808-707-606',
         
     | 
| 
      
 81 
     | 
    
         
            +
              first_name: 'Swaleh',
         
     | 
| 
      
 82 
     | 
    
         
            +
              last_name: 'Mdoe',
         
     | 
| 
      
 83 
     | 
    
         
            +
              email: 'user@example.com',
         
     | 
| 
      
 84 
     | 
    
         
            +
              phonenumber: '+254722222222',
         
     | 
| 
      
 85 
     | 
    
         
            +
              currency: 'KES'
         
     | 
| 
      
 86 
     | 
    
         
            +
            }
         
     | 
| 
      
 87 
     | 
    
         
            +
            ```
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            Then generate the transaction url as below. In the example, the value is
         
     | 
| 
      
 90 
     | 
    
         
            +
            assigned to the variable `order_url` which you can pass on to the templating
         
     | 
| 
      
 91 
     | 
    
         
            +
            system of your choice to generate an iframe. Please note that this method
         
     | 
| 
      
 92 
     | 
    
         
            +
            utilizes all that information set in the previous steps in generating the url so
         
     | 
| 
      
 93 
     | 
    
         
            +
            it's important that it's the last step in the post order process.
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 96 
     | 
    
         
            +
            # generate transaction url
         
     | 
| 
      
 97 
     | 
    
         
            +
            order_url = pesapal.generate_order_url
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            # order_url will a string with the url example;
         
     | 
| 
      
 100 
     | 
    
         
            +
            # 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
         
     | 
| 
      
 101 
     | 
    
         
            +
            ```
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            _Ps: Please note the `:callback_url` value in the `pesapal.config` hash ...
         
     | 
| 
      
 104 
     | 
    
         
            +
            after the user successfully posts the order, the response will be sent to this
         
     | 
| 
      
 105 
     | 
    
         
            +
            url. Refer to [official Pesapal Step-By-Step integration guide][18] for more
         
     | 
| 
      
 106 
     | 
    
         
            +
            details._
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            ### Querying Payment Status
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            Use this to query the status of the transaction. When a transaction is posted to
         
     | 
| 
      
 111 
     | 
    
         
            +
            Pesapal, it may be in a PENDING, COMPLETED, FAILED or INVALID state. If the
         
     | 
| 
      
 112 
     | 
    
         
            +
            transaction is PENDING, the payment may complete or fail at a later stage.
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            Both the unique merchant reference generated by your system (compulsory) and the
         
     | 
| 
      
 115 
     | 
    
         
            +
            pesapal transaction tracking id (optional) are input parameters to this method
         
     | 
| 
      
 116 
     | 
    
         
            +
            but if you don't ensure that the merchant reference is unique for each order on
         
     | 
| 
      
 117 
     | 
    
         
            +
            your system, you may get INVALID as the response. Because of this, it is
         
     | 
| 
      
 118 
     | 
    
         
            +
            recommended that you provide both the merchant reference and transaction
         
     | 
| 
      
 119 
     | 
    
         
            +
            tracking id as parameters to guarantee uniqueness.
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 122 
     | 
    
         
            +
            # option 1: using merchant reference only
         
     | 
| 
      
 123 
     | 
    
         
            +
            payment_status = pesapal.query_payment_status("<MERCHANT_REFERENCE>")
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            # option 2: using merchant reference and transaction id (recommended)
         
     | 
| 
      
 126 
     | 
    
         
            +
            payment_status = pesapal.query_payment_status("<MERCHANT_REFERENCE>","<TRANSACTION_ID>")
         
     | 
| 
      
 127 
     | 
    
         
            +
            ```
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            ### Querying Payment Details
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            Same as querying payment status above, but the return value contains more
         
     | 
| 
      
 132 
     | 
    
         
            +
            information (and is a hash as opposed to a string).
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 135 
     | 
    
         
            +
            # pass in merchant reference and transaction id
         
     | 
| 
      
 136 
     | 
    
         
            +
            payment_details = pesapal.query_payment_details("<MERCHANT_REFERENCE>","<TRANSACTION_ID>")
         
     | 
| 
      
 137 
     | 
    
         
            +
            ```
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            The result is a hash that looks something like this ...
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 142 
     | 
    
         
            +
            {
         
     | 
| 
      
 143 
     | 
    
         
            +
              method: "<PAYMENT_METHOD>",
         
     | 
| 
      
 144 
     | 
    
         
            +
              status: "<PAYMENT_STATUS>",
         
     | 
| 
      
 145 
     | 
    
         
            +
              merchant_reference: "<MERCHANT_REFERENCE>",
         
     | 
| 
      
 146 
     | 
    
         
            +
              transaction_tracking_id: "<TRANSACTION_ID>"
         
     | 
| 
      
 147 
     | 
    
         
            +
            }
         
     | 
| 
      
 148 
     | 
    
         
            +
            ```
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            ### IPN Listening
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            Use the `ipn_listener` method to listen to Pesapal IPN calls to easily create an
         
     | 
| 
      
 153 
     | 
    
         
            +
            appropriate response, example below.
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 156 
     | 
    
         
            +
            # pass in the notification type, merchant reference and transaction id
         
     | 
| 
      
 157 
     | 
    
         
            +
            response_to_ipn = pesapal.ipn_listener("<NOTIFICATION_TYPE>", "<MERCHANT_REFERENCE>","<TRANSACTION_ID>")
         
     | 
| 
      
 158 
     | 
    
         
            +
            ```
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            The variable, `response_to_ipn`, now holds a response as the one shown below.
         
     | 
| 
      
 161 
     | 
    
         
            +
            Using the status you can customise any actions (e.g. database inserts and
         
     | 
| 
      
 162 
     | 
    
         
            +
            updates) and finally, it's up to you to send the `:response` back to pesapal. The
         
     | 
| 
      
 163 
     | 
    
         
            +
            hard part is done for you.
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 166 
     | 
    
         
            +
            {
         
     | 
| 
      
 167 
     | 
    
         
            +
              status: "<PAYMENT_STATUS>",
         
     | 
| 
      
 168 
     | 
    
         
            +
              response: "<IPN_RESPONSE>"
         
     | 
| 
      
 169 
     | 
    
         
            +
            }
         
     | 
| 
      
 170 
     | 
    
         
            +
            ```
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            _Ps: Refer to Pesapal official documentation to make sure you understand what
         
     | 
| 
      
 173 
     | 
    
         
            +
            data Pesapal sends to IPN and what result they expect back._
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            Support & Issues
         
     | 
| 
      
 177 
     | 
    
         
            +
            ----------------
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
            In case you are having any issues using this gem please **_do not_** email me
         
     | 
| 
      
 180 
     | 
    
         
            +
            directly, I'd rather you [submit new issues (and even requests) here][23] ...
         
     | 
| 
      
 181 
     | 
    
         
            +
            obviously after [checking if the issue has already been raised and closed][6].
         
     | 
| 
      
 182 
     | 
    
         
            +
            This way, other people get to share in the conversation that would have been
         
     | 
| 
      
 183 
     | 
    
         
            +
            private and out of their reach.
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            Contributing
         
     | 
| 
      
 187 
     | 
    
         
            +
            ------------
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
            ### To gem's code
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
            Submitting a pull request;
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
            1. [Fork the repository][fork].
         
     | 
| 
      
 194 
     | 
    
         
            +
            2. [Create a topic branch][branch] (`git checkout -b BRANCH_NAME`).
         
     | 
| 
      
 195 
     | 
    
         
            +
            3. [Install bundler][bundler].
         
     | 
| 
      
 196 
     | 
    
         
            +
            4. Check that tests pass with `rspec spec`.
         
     | 
| 
      
 197 
     | 
    
         
            +
            5. Write a failing test to capture existing bug or lack of feature.
         
     | 
| 
      
 198 
     | 
    
         
            +
            6. Run `rspec spec` to verify that test fails.
         
     | 
| 
      
 199 
     | 
    
         
            +
            7. Implement your feature or bug fix.
         
     | 
| 
      
 200 
     | 
    
         
            +
            8. Ensure tests pass.
         
     | 
| 
      
 201 
     | 
    
         
            +
            9. If it's a new feature or a bug fix, please add an entry to the CHANGELOG file.
         
     | 
| 
      
 202 
     | 
    
         
            +
            10. Check code style violations using [Rubocop][rubocop].
         
     | 
| 
      
 203 
     | 
    
         
            +
            11. Add a commit (`git commit -am 'AWESOME COMMIT MESSAGE'`).
         
     | 
| 
      
 204 
     | 
    
         
            +
            12. Push your changes to the branch (`git push origin BRANCH_NAME`).
         
     | 
| 
      
 205 
     | 
    
         
            +
            13. [Submit a pull request.][pr]
         
     | 
| 
      
 206 
     | 
    
         
            +
            14. You will get some feedback and may need to push additional commits
         
     | 
| 
      
 207 
     | 
    
         
            +
                with more fixes to the same branch; this will update your pull request
         
     | 
| 
      
 208 
     | 
    
         
            +
                automatically.
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
            [branch]: http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches
         
     | 
| 
      
 211 
     | 
    
         
            +
            [bundler]: http://bundler.io
         
     | 
| 
      
 212 
     | 
    
         
            +
            [fork]: https://help.github.com/articles/fork-a-repo/
         
     | 
| 
      
 213 
     | 
    
         
            +
            [pr]: https://help.github.com/articles/using-pull-requests
         
     | 
| 
      
 214 
     | 
    
         
            +
            [rubocop]: https://github.com/bbatsov/rubocop
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
            ### To gem's documentation
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            Gem documentation is of two types, feel free to contribute to any;
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
            1. Gem home page at [itskingori.github.io/pesapal-gem][26] _(simple step-by-step)_
         
     | 
| 
      
 222 
     | 
    
         
            +
            2. API documetation generated by [Yard][25] _(very comprehensive)_
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            Gem home page is built on [Jekyll][27], which is a fun and easy to use static
         
     | 
| 
      
 225 
     | 
    
         
            +
            site generator and [hosted on GitHub Pages][30]. The code is in the `docs/`
         
     | 
| 
      
 226 
     | 
    
         
            +
            folder if you want to have a peek.
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
            Preview the gem API documentation locally by installing [Yard][25] (`gem install
         
     | 
| 
      
 229 
     | 
    
         
            +
            yard`) and call `$ yard server` to set up a local documentation server usually
         
     | 
| 
      
 230 
     | 
    
         
            +
            running on `http://0.0.0.0:8808`. The result should be similar to the API
         
     | 
| 
      
 231 
     | 
    
         
            +
            documention up on [rubydoc.info/gems/pesapal][13].
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
            _Ps: If you've written code and can't figure out why they aren't passing (or if
         
     | 
| 
      
 234 
     | 
    
         
            +
            you've written your own tests ... just send a pull a request. We can then do a
         
     | 
| 
      
 235 
     | 
    
         
            +
            [code review][32])_.
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
            Testing
         
     | 
| 
      
 239 
     | 
    
         
            +
            -------
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
            Tests run [RSpec][31] which is a Behaviour-Driven Development tool. To run
         
     | 
| 
      
 242 
     | 
    
         
            +
            tests, call;
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 245 
     | 
    
         
            +
            $ bundle exec rspec spec
         
     | 
| 
      
 246 
     | 
    
         
            +
            ```
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
            References
         
     | 
| 
      
 250 
     | 
    
         
            +
            ----------
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
            * [oAuth 1.0 Spec][1]
         
     | 
| 
      
 253 
     | 
    
         
            +
            * [Developing a RubyGem using Bundler][2]
         
     | 
| 
      
 254 
     | 
    
         
            +
            * [RailsGuides][20]
         
     | 
| 
      
 255 
     | 
    
         
            +
            * [Make your own gem][3]
         
     | 
| 
      
 256 
     | 
    
         
            +
            * [Getting started with RSpec][33]
         
     | 
| 
      
 257 
     | 
    
         
            +
            * [Pesapal API Reference (Official)][4]
         
     | 
| 
      
 258 
     | 
    
         
            +
            * [Pesapal Step-By-Step Reference (Official)][18]
         
     | 
| 
      
 259 
     | 
    
         
            +
            * [Pesapal PHP API Reference (Unofficial)][5]
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
            License
         
     | 
| 
      
 263 
     | 
    
         
            +
            -------
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
            [King'ori J. Maina][10] © 2013-{{ 'now' | date: "%Y" }}. The [MIT License bundled therein][11] is a
         
     | 
| 
      
 266 
     | 
    
         
            +
            permissive license that is short and to the point. It lets people do anything
         
     | 
| 
      
 267 
     | 
    
         
            +
            they want as long as they provide attribution and waive liability.
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
            [1]: http://oauth.net/core/1.0/
         
     | 
| 
      
 271 
     | 
    
         
            +
            [2]: https://github.com/radar/guides/blob/master/gem-development.md
         
     | 
| 
      
 272 
     | 
    
         
            +
            [3]: http://guides.rubygems.org/make-your-own-gem/
         
     | 
| 
      
 273 
     | 
    
         
            +
            [4]: http://developer.pesapal.com/how-to-integrate/api-reference
         
     | 
| 
      
 274 
     | 
    
         
            +
            [5]: https://github.com/itskingori/pesapal-php#pesapal-php-api-reference-unofficial
         
     | 
| 
      
 275 
     | 
    
         
            +
            [6]: https://github.com/itskingori/pesapal-gem/issues?state=closed
         
     | 
| 
      
 276 
     | 
    
         
            +
            [7]: https://rubygems.org/gems/pesapal
         
     | 
| 
      
 277 
     | 
    
         
            +
            [8]: https://github.com/itskingori/pesapal-gem/fork
         
     | 
| 
      
 278 
     | 
    
         
            +
            [9]: https://github.com/itskingori/pesapal-gem#contributing--testing
         
     | 
| 
      
 279 
     | 
    
         
            +
            [10]: http://kingori.co/
         
     | 
| 
      
 280 
     | 
    
         
            +
            [11]: https://raw.githubusercontent.com/itskingori/pesapal-gem/master/LICENSE.txt
         
     | 
| 
      
 281 
     | 
    
         
            +
            [12]: https://github.com/itskingori/pesapal-gem/releases/
         
     | 
| 
      
 282 
     | 
    
         
            +
            [13]: http://rubydoc.info/gems/pesapal/frames/file/README.md
         
     | 
| 
      
 283 
     | 
    
         
            +
            [14]: https://github.com/itskingori/mo
         
     | 
| 
      
 284 
     | 
    
         
            +
            [15]: https://github.com/itskingori/mo/tree/master/convention#-convention
         
     | 
| 
      
 285 
     | 
    
         
            +
            [16]: http://kingori.co/articles/2013/09/modus-operandi/
         
     | 
| 
      
 286 
     | 
    
         
            +
            [17]: https://github.com/itskingori/pesapal-gem/pulls
         
     | 
| 
      
 287 
     | 
    
         
            +
            [18]: http://developer.pesapal.com/how-to-integrate/step-by-step
         
     | 
| 
      
 288 
     | 
    
         
            +
            [19]: https://github.com/itskingori/pesapal-gem/graphs/contributors
         
     | 
| 
      
 289 
     | 
    
         
            +
            [20]: http://guides.rubyonrails.org/
         
     | 
| 
      
 290 
     | 
    
         
            +
            [21]: https://raw.githubusercontent.com/itskingori/pesapal-gem/master/CHANGELOG.md
         
     | 
| 
      
 291 
     | 
    
         
            +
            [22]: https://travis-ci.org/itskingori/pesapal-gem/pull_requests
         
     | 
| 
      
 292 
     | 
    
         
            +
            [23]: https://github.com/itskingori/pesapal-gem/issues/new
         
     | 
| 
      
 293 
     | 
    
         
            +
            [24]: https://www.pesapal.com/
         
     | 
| 
      
 294 
     | 
    
         
            +
            [25]: http://yardoc.org/
         
     | 
| 
      
 295 
     | 
    
         
            +
            [26]: https://itskingori.github.io/pesapal-gem
         
     | 
| 
      
 296 
     | 
    
         
            +
            [27]: http://jekyllrb.com/
         
     | 
| 
      
 297 
     | 
    
         
            +
            [28]: http://jekyllrb.com/docs/home/
         
     | 
| 
      
 298 
     | 
    
         
            +
            [29]: https://github.com/itskingori/pesapal-gem/tree/gh-pages
         
     | 
| 
      
 299 
     | 
    
         
            +
            [30]: https://pages.github.com/
         
     | 
| 
      
 300 
     | 
    
         
            +
            [31]: https://relishapp.com/rspec/
         
     | 
| 
      
 301 
     | 
    
         
            +
            [32]: http://en.wikipedia.org/wiki/Code_review
         
     | 
| 
      
 302 
     | 
    
         
            +
            [33]: https://relishapp.com/rspec/docs/gettingstarted
         
     | 
    
        data/lib/pesapal.rb
    CHANGED
    
    
| 
         @@ -43,10 +43,12 @@ module Pesapal 
     | 
|
| 
       43 
43 
     | 
    
         
             
                  #   query parameters and the `oauth_signature` itself.
         
     | 
| 
       44 
44 
     | 
    
         
             
                  def self.set_parameters(consumer_key, merchant_reference, transaction_tracking_id)
         
     | 
| 
       45 
45 
     | 
    
         
             
                    timestamp = Time.now.to_i.to_s
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    {
         
     | 
| 
      
 48 
     | 
    
         
            +
                      oauth_consumer_key: consumer_key,
         
     | 
| 
      
 49 
     | 
    
         
            +
                      oauth_nonce: timestamp + Pesapal::Oauth.generate_nonce(12),
         
     | 
| 
       48 
50 
     | 
    
         
             
                      oauth_signature_method: 'HMAC-SHA1',
         
     | 
| 
       49 
     | 
    
         
            -
                      oauth_timestamp:  
     | 
| 
      
 51 
     | 
    
         
            +
                      oauth_timestamp: timestamp,
         
     | 
| 
       50 
52 
     | 
    
         
             
                      oauth_version: '1.0',
         
     | 
| 
       51 
53 
     | 
    
         
             
                      pesapal_merchant_reference: merchant_reference,
         
     | 
| 
       52 
54 
     | 
    
         
             
                      pesapal_transaction_tracking_id: transaction_tracking_id
         
     | 
    
        data/lib/pesapal/helper/post.rb
    CHANGED
    
    | 
         @@ -163,11 +163,13 @@ module Pesapal 
     | 
|
| 
       163 
163 
     | 
    
         
             
                  # @return [Hash] parameters to be used in generating the oAuth 1.0 URL query parameters and the `oauth_signature` itself.
         
     | 
| 
       164 
164 
     | 
    
         
             
                  def self.set_parameters(callback_url, consumer_key, post_xml)
         
     | 
| 
       165 
165 
     | 
    
         
             
                    timestamp = Time.now.to_i.to_s
         
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                    {
         
     | 
| 
      
 168 
     | 
    
         
            +
                      oauth_callback: callback_url,
         
     | 
| 
       167 
169 
     | 
    
         
             
                      oauth_consumer_key: consumer_key,
         
     | 
| 
       168 
     | 
    
         
            -
                      oauth_nonce:  
     | 
| 
      
 170 
     | 
    
         
            +
                      oauth_nonce: timestamp + Pesapal::Oauth.generate_nonce(12),
         
     | 
| 
       169 
171 
     | 
    
         
             
                      oauth_signature_method: 'HMAC-SHA1',
         
     | 
| 
       170 
     | 
    
         
            -
                      oauth_timestamp:  
     | 
| 
      
 172 
     | 
    
         
            +
                      oauth_timestamp: timestamp,
         
     | 
| 
       171 
173 
     | 
    
         
             
                      oauth_version: '1.0',
         
     | 
| 
       172 
174 
     | 
    
         
             
                      pesapal_request_data: post_xml
         
     | 
| 
       173 
175 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -39,13 +39,14 @@ module Pesapal 
     | 
|
| 
       39 
39 
     | 
    
         
             
                  # @return [Hash] parameters to be used in generating the oAuth 1.0 URL query parameters and the `oauth_signature` itself.
         
     | 
| 
       40 
40 
     | 
    
         
             
                  def self.set_parameters(consumer_key, merchant_reference, transaction_tracking_id = nil)
         
     | 
| 
       41 
41 
     | 
    
         
             
                    timestamp = Time.now.to_i.to_s
         
     | 
| 
       42 
     | 
    
         
            -
                    params = { 
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
                    params = {
         
     | 
| 
      
 43 
     | 
    
         
            +
                      oauth_consumer_key: consumer_key,
         
     | 
| 
      
 44 
     | 
    
         
            +
                      oauth_nonce: timestamp + Pesapal::Oauth.generate_nonce(12),
         
     | 
| 
      
 45 
     | 
    
         
            +
                      oauth_signature_method: 'HMAC-SHA1',
         
     | 
| 
      
 46 
     | 
    
         
            +
                      oauth_timestamp: timestamp,
         
     | 
| 
      
 47 
     | 
    
         
            +
                      oauth_version: '1.0',
         
     | 
| 
      
 48 
     | 
    
         
            +
                      pesapal_merchant_reference: merchant_reference
         
     | 
| 
      
 49 
     | 
    
         
            +
                    }
         
     | 
| 
       49 
50 
     | 
    
         
             
                    params[:pesapal_transaction_tracking_id] = transaction_tracking_id unless transaction_tracking_id.nil?
         
     | 
| 
       50 
51 
     | 
    
         
             
                    params
         
     | 
| 
       51 
52 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/pesapal/merchant.rb
    CHANGED
    
    | 
         @@ -64,7 +64,7 @@ module Pesapal 
     | 
|
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         
             
                private
         
     | 
| 
       66 
66 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                attr_reader : 
     | 
| 
      
 67 
     | 
    
         
            +
                attr_reader :env
         
     | 
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
                def params
         
     | 
| 
       70 
70 
     | 
    
         
             
                  @params ||= nil
         
     | 
| 
         @@ -87,71 +87,22 @@ module Pesapal 
     | 
|
| 
       87 
87 
     | 
    
         
             
                # will interact with the testing or the live Pesapal API. Like so ...
         
     | 
| 
       88 
88 
     | 
    
         
             
                #
         
     | 
| 
       89 
89 
     | 
    
         
             
                # ```ruby
         
     | 
| 
       90 
     | 
    
         
            -
                # # Sets environment  
     | 
| 
       91 
     | 
    
         
            -
                # pesapal = Pesapal::Merchant.new
         
     | 
| 
       92 
     | 
    
         
            -
                #
         
     | 
| 
       93 
     | 
    
         
            -
                # # Sets environment to :development
         
     | 
| 
      
 90 
     | 
    
         
            +
                # # Sets environment to :development explicitly
         
     | 
| 
       94 
91 
     | 
    
         
             
                # pesapal = Pesapal::Merchant.new(:development)
         
     | 
| 
       95 
92 
     | 
    
         
             
                #
         
     | 
| 
       96 
93 
     | 
    
         
             
                # # Sets environment to :production
         
     | 
| 
       97 
94 
     | 
    
         
             
                # pesapal = Pesapal::Merchant.new(:production)
         
     | 
| 
       98 
95 
     | 
    
         
             
                # ```
         
     | 
| 
       99 
96 
     | 
    
         
             
                #
         
     | 
| 
       100 
     | 
    
         
            -
                # A few things to note about the constructor as it behaves differently
         
     | 
| 
       101 
     | 
    
         
            -
                # depending on the context within which it is called i.e. _Rails_ app vs
         
     | 
| 
       102 
     | 
    
         
            -
                # _non-Rails_ app ...
         
     | 
| 
       103 
     | 
    
         
            -
                #
         
     | 
| 
       104 
     | 
    
         
            -
                # ### Case 1: Rails app
         
     | 
| 
       105 
     | 
    
         
            -
                #
         
     | 
| 
       106 
     | 
    
         
            -
                # The constructor attempts to set configuration details that should be
         
     | 
| 
       107 
     | 
    
         
            -
                # available at runtime from `Rails.application.config.pesapal_credentials`.
         
     | 
| 
       108 
     | 
    
         
            -
                # This contains values loaded at application start from a YAML file located
         
     | 
| 
       109 
     | 
    
         
            -
                # at `config/pesapal.yml` which typically looks like this:
         
     | 
| 
       110 
     | 
    
         
            -
                #
         
     | 
| 
       111 
     | 
    
         
            -
                #  ```yaml
         
     | 
| 
       112 
     | 
    
         
            -
                # development:
         
     | 
| 
       113 
     | 
    
         
            -
                #   callback_url: 'http://0.0.0.0:3000/pesapal/callback'
         
     | 
| 
       114 
     | 
    
         
            -
                #   consumer_key: '<YOUR_DEV_CONSUMER_KEY>'
         
     | 
| 
       115 
     | 
    
         
            -
                #   consumer_secret: '<YOUR_DEV_CONSUMER_SECRET>'
         
     | 
| 
       116 
     | 
    
         
            -
                #
         
     | 
| 
       117 
     | 
    
         
            -
                # production:
         
     | 
| 
       118 
     | 
    
         
            -
                #   callback_url: 'http://1.2.3.4:3000/pesapal/callback'
         
     | 
| 
       119 
     | 
    
         
            -
                #   consumer_key: '<YOUR_PROD_CONSUMER_KEY>'
         
     | 
| 
       120 
     | 
    
         
            -
                #   consumer_secret: '<YOUR_PROD_CONSUMER_SECRET>'
         
     | 
| 
       121 
     | 
    
         
            -
                # ```
         
     | 
| 
       122 
     | 
    
         
            -
                #
         
     | 
| 
       123 
     | 
    
         
            -
                # The appropriate credentials are picked and set to {#config} instance
         
     | 
| 
       124 
     | 
    
         
            -
                # attribute depending on set environment. The setting of environment is
         
     | 
| 
       125 
     | 
    
         
            -
                # explained above. It's worth nothing that if for some reason the YAML file
         
     | 
| 
       126 
     | 
    
         
            -
                # could not be read, then it fallbacks to setting {#config} instance
         
     | 
| 
       127 
     | 
    
         
            -
                # attribute with default values. The exact definition of default values is
         
     | 
| 
       128 
     | 
    
         
            -
                # shown below.
         
     | 
| 
       129 
     | 
    
         
            -
                #
         
     | 
| 
       130 
     | 
    
         
            -
                # ### Case 2: Non-Rails app
         
     | 
| 
       131 
     | 
    
         
            -
                #
         
     | 
| 
       132 
     | 
    
         
            -
                # Since (and if) no predefined configuration files are available, the
         
     | 
| 
       133 
     | 
    
         
            -
                # constructor sets the {#config} instance attribute up with default values
         
     | 
| 
       134 
     | 
    
         
            -
                # as shown below:
         
     | 
| 
       135 
     | 
    
         
            -
                #
         
     | 
| 
       136 
     | 
    
         
            -
                # ```
         
     | 
| 
       137 
     | 
    
         
            -
                # {  :callback_url => 'http://0.0.0.0:3000/pesapal/callback',
         
     | 
| 
       138 
     | 
    
         
            -
                #    :consumer_key => '<YOUR_CONSUMER_KEY>',
         
     | 
| 
       139 
     | 
    
         
            -
                #    :consumer_secret => '<YOUR_CONSUMER_SECRET>'
         
     | 
| 
       140 
     | 
    
         
            -
                # }
         
     | 
| 
       141 
     | 
    
         
            -
                # ```
         
     | 
| 
       142 
     | 
    
         
            -
                #
         
     | 
| 
       143 
     | 
    
         
            -
                # @note You can change the environment at runtime using {#change_env}
         
     | 
| 
       144 
     | 
    
         
            -
                #
         
     | 
| 
       145 
97 
     | 
    
         
             
                # @param env [Symbol] the environment we want to use i.e. `:development` or
         
     | 
| 
       146 
     | 
    
         
            -
                #   `:production`. 
     | 
| 
       147 
     | 
    
         
            -
                 
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
                   
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
                     
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
                #   `:production`.
         
     | 
| 
      
 99 
     | 
    
         
            +
                def initialize(env = :development)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  @env = env.to_s.downcase
         
     | 
| 
      
 101 
     | 
    
         
            +
                  @config = {
         
     | 
| 
      
 102 
     | 
    
         
            +
                    callback_url: 'http://0.0.0.0:3000/pesapal/callback',
         
     | 
| 
      
 103 
     | 
    
         
            +
                    consumer_key: '<YOUR_CONSUMER_KEY>',
         
     | 
| 
      
 104 
     | 
    
         
            +
                    consumer_secret: '<YOUR_CONSUMER_SECRET>'
         
     | 
| 
      
 105 
     | 
    
         
            +
                  }
         
     | 
| 
       155 
106 
     | 
    
         
             
                end
         
     | 
| 
       156 
107 
     | 
    
         | 
| 
       157 
108 
     | 
    
         
             
                # Generate URL that's used to post a transaction to PesaPal.
         
     | 
| 
         @@ -185,17 +136,20 @@ module Pesapal 
     | 
|
| 
       185 
136 
     | 
    
         
             
                  # build xml with input data, the format is standard so no editing is
         
     | 
| 
       186 
137 
     | 
    
         
             
                  # required
         
     | 
| 
       187 
138 
     | 
    
         
             
                  @post_xml = Pesapal::Helper::Post.generate_post_xml @order_details
         
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
139 
     | 
    
         
             
                  # initialize setting of @params (oauth_signature left empty)
         
     | 
| 
       190 
140 
     | 
    
         
             
                  @params = Pesapal::Helper::Post.set_parameters(@config[:callback_url], @config[:consumer_key], @post_xml)
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
141 
     | 
    
         
             
                  # generate oauth signature and add signature to the request parameters
         
     | 
| 
       193 
     | 
    
         
            -
                  @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature( 
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
      
 142 
     | 
    
         
            +
                  @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature(
         
     | 
| 
      
 143 
     | 
    
         
            +
                    'GET',
         
     | 
| 
      
 144 
     | 
    
         
            +
                    postpesapaldirectorderv4_url,
         
     | 
| 
      
 145 
     | 
    
         
            +
                    @params,
         
     | 
| 
      
 146 
     | 
    
         
            +
                    @config[:consumer_secret],
         
     | 
| 
      
 147 
     | 
    
         
            +
                    @token_secret
         
     | 
| 
      
 148 
     | 
    
         
            +
                  )
         
     | 
| 
       195 
149 
     | 
    
         
             
                  # change params (with signature) to a query string
         
     | 
| 
       196 
150 
     | 
    
         
             
                  query_string = Pesapal::Oauth.generate_encoded_params_query_string @params
         
     | 
| 
       197 
151 
     | 
    
         | 
| 
       198 
     | 
    
         
            -
                  "#{ 
     | 
| 
      
 152 
     | 
    
         
            +
                  "#{postpesapaldirectorderv4_url}?#{query_string}"
         
     | 
| 
       199 
153 
     | 
    
         
             
                end
         
     | 
| 
       200 
154 
     | 
    
         | 
| 
       201 
155 
     | 
    
         
             
                # Same as {#query_payment_status}, but additional information is returned in
         
     | 
| 
         @@ -237,15 +191,19 @@ module Pesapal 
     | 
|
| 
       237 
191 
     | 
    
         
             
                def query_payment_details(merchant_reference, transaction_tracking_id)
         
     | 
| 
       238 
192 
     | 
    
         
             
                  # initialize setting of @params (oauth_signature left empty)
         
     | 
| 
       239 
193 
     | 
    
         
             
                  @params = Pesapal::Helper::Details.set_parameters(@config[:consumer_key], merchant_reference, transaction_tracking_id)
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
194 
     | 
    
         
             
                  # generate oauth signature and add signature to the request parameters
         
     | 
| 
       242 
     | 
    
         
            -
                  @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature( 
     | 
| 
       243 
     | 
    
         
            -
             
     | 
| 
      
 195 
     | 
    
         
            +
                  @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature(
         
     | 
| 
      
 196 
     | 
    
         
            +
                    'GET',
         
     | 
| 
      
 197 
     | 
    
         
            +
                    querypaymentdetails_url,
         
     | 
| 
      
 198 
     | 
    
         
            +
                    @params,
         
     | 
| 
      
 199 
     | 
    
         
            +
                    @config[:consumer_secret],
         
     | 
| 
      
 200 
     | 
    
         
            +
                    @token_secret
         
     | 
| 
      
 201 
     | 
    
         
            +
                  )
         
     | 
| 
       244 
202 
     | 
    
         
             
                  # change params (with signature) to a query string
         
     | 
| 
       245 
203 
     | 
    
         
             
                  query_string = Pesapal::Oauth.generate_encoded_params_query_string @params
         
     | 
| 
       246 
204 
     | 
    
         | 
| 
       247 
205 
     | 
    
         
             
                  # get status response
         
     | 
| 
       248 
     | 
    
         
            -
                  uri = URI.parse "#{ 
     | 
| 
      
 206 
     | 
    
         
            +
                  uri = URI.parse "#{querypaymentdetails_url}?#{query_string}"
         
     | 
| 
       249 
207 
     | 
    
         
             
                  http = Net::HTTP.new(uri.host, uri.port)
         
     | 
| 
       250 
208 
     | 
    
         
             
                  http.use_ssl = true
         
     | 
| 
       251 
209 
     | 
    
         
             
                  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
         
     | 
| 
         @@ -253,7 +211,8 @@ module Pesapal 
     | 
|
| 
       253 
211 
     | 
    
         
             
                  response = CGI.parse response.body
         
     | 
| 
       254 
212 
     | 
    
         
             
                  response = response['pesapal_response_data'][0].split(',')
         
     | 
| 
       255 
213 
     | 
    
         | 
| 
       256 
     | 
    
         
            -
                  { 
     | 
| 
      
 214 
     | 
    
         
            +
                  {
         
     | 
| 
      
 215 
     | 
    
         
            +
                    method: response[1],
         
     | 
| 
       257 
216 
     | 
    
         
             
                    status: response[2],
         
     | 
| 
       258 
217 
     | 
    
         
             
                    merchant_reference: response[3],
         
     | 
| 
       259 
218 
     | 
    
         
             
                    transaction_tracking_id: response[0]
         
     | 
| 
         @@ -290,15 +249,19 @@ module Pesapal 
     | 
|
| 
       290 
249 
     | 
    
         
             
                def query_payment_status(merchant_reference, transaction_tracking_id = nil)
         
     | 
| 
       291 
250 
     | 
    
         
             
                  # initialize setting of @params (oauth_signature left empty)
         
     | 
| 
       292 
251 
     | 
    
         
             
                  @params = Pesapal::Helper::Status.set_parameters(@config[:consumer_key], merchant_reference, transaction_tracking_id)
         
     | 
| 
       293 
     | 
    
         
            -
             
     | 
| 
       294 
252 
     | 
    
         
             
                  # generate oauth signature and add signature to the request parameters
         
     | 
| 
       295 
     | 
    
         
            -
                  @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature( 
     | 
| 
       296 
     | 
    
         
            -
             
     | 
| 
      
 253 
     | 
    
         
            +
                  @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature(
         
     | 
| 
      
 254 
     | 
    
         
            +
                    'GET',
         
     | 
| 
      
 255 
     | 
    
         
            +
                    querypaymentstatus_url,
         
     | 
| 
      
 256 
     | 
    
         
            +
                    @params,
         
     | 
| 
      
 257 
     | 
    
         
            +
                    @config[:consumer_secret],
         
     | 
| 
      
 258 
     | 
    
         
            +
                    @token_secret
         
     | 
| 
      
 259 
     | 
    
         
            +
                  )
         
     | 
| 
       297 
260 
     | 
    
         
             
                  # change params (with signature) to a query string
         
     | 
| 
       298 
261 
     | 
    
         
             
                  query_string = Pesapal::Oauth.generate_encoded_params_query_string @params
         
     | 
| 
       299 
262 
     | 
    
         | 
| 
       300 
263 
     | 
    
         
             
                  # get status response
         
     | 
| 
       301 
     | 
    
         
            -
                  uri = URI.parse "#{ 
     | 
| 
      
 264 
     | 
    
         
            +
                  uri = URI.parse "#{querypaymentstatus_url}?#{query_string}"
         
     | 
| 
       302 
265 
     | 
    
         
             
                  http = Net::HTTP.new(uri.host, uri.port)
         
     | 
| 
       303 
266 
     | 
    
         
             
                  http.use_ssl = true
         
     | 
| 
       304 
267 
     | 
    
         
             
                  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
         
     | 
| 
         @@ -307,50 +270,6 @@ module Pesapal 
     | 
|
| 
       307 
270 
     | 
    
         
             
                  response['pesapal_response_data'][0]
         
     | 
| 
       308 
271 
     | 
    
         
             
                end
         
     | 
| 
       309 
272 
     | 
    
         | 
| 
       310 
     | 
    
         
            -
                # Set the environment in use.
         
     | 
| 
       311 
     | 
    
         
            -
                #
         
     | 
| 
       312 
     | 
    
         
            -
                # Useful especially if you want to change the environment at runtime from
         
     | 
| 
       313 
     | 
    
         
            -
                # what was set during initialization in the constructor. It also makes sure
         
     | 
| 
       314 
     | 
    
         
            -
                # that we use the appropriate endpoints when making calls to Pesapal. See
         
     | 
| 
       315 
     | 
    
         
            -
                # below:
         
     | 
| 
       316 
     | 
    
         
            -
                #
         
     | 
| 
       317 
     | 
    
         
            -
                # ```
         
     | 
| 
       318 
     | 
    
         
            -
                # # endpoint values set if :development
         
     | 
| 
       319 
     | 
    
         
            -
                # {
         
     | 
| 
       320 
     | 
    
         
            -
                #  :postpesapaldirectorderv4 => "http://demo.pesapal.com/API/PostPesapalDirectOrderV4",
         
     | 
| 
       321 
     | 
    
         
            -
                #  :querypaymentstatus => "http://demo.pesapal.com/API/QueryPaymentStatus",
         
     | 
| 
       322 
     | 
    
         
            -
                #  :querypaymentdetails => "http://demo.pesapal.com/API/QueryPaymentDetails"
         
     | 
| 
       323 
     | 
    
         
            -
                # }
         
     | 
| 
       324 
     | 
    
         
            -
                #
         
     | 
| 
       325 
     | 
    
         
            -
                # # endpoint values set if :production
         
     | 
| 
       326 
     | 
    
         
            -
                # {
         
     | 
| 
       327 
     | 
    
         
            -
                #  :postpesapaldirectorderv4 => "https://www.pesapal.com/API/PostPesapalDirectOrderV4",
         
     | 
| 
       328 
     | 
    
         
            -
                #  :querypaymentstatus => "https://www.pesapal.com/API/QueryPaymentStatus",
         
     | 
| 
       329 
     | 
    
         
            -
                #  :querypaymentdetails => "https://www.pesapal.com/API/QueryPaymentDetails"
         
     | 
| 
       330 
     | 
    
         
            -
                # }
         
     | 
| 
       331 
     | 
    
         
            -
                # ```
         
     | 
| 
       332 
     | 
    
         
            -
                #
         
     | 
| 
       333 
     | 
    
         
            -
                # @note For a Rails app, you'd expect that calling this would also flip the
         
     | 
| 
       334 
     | 
    
         
            -
                #   credentials if there was a YAML file containing both environment
         
     | 
| 
       335 
     | 
    
         
            -
                #   credentials but that's not the case. It could be something that we can
         
     | 
| 
       336 
     | 
    
         
            -
                #   add later.
         
     | 
| 
       337 
     | 
    
         
            -
                #
         
     | 
| 
       338 
     | 
    
         
            -
                # @param env [Symbol] the environment we want to use i.e. :development or
         
     | 
| 
       339 
     | 
    
         
            -
                #   :production
         
     | 
| 
       340 
     | 
    
         
            -
                #
         
     | 
| 
       341 
     | 
    
         
            -
                # @return [Hash] contains Pesapal endpoints appropriate for the set
         
     | 
| 
       342 
     | 
    
         
            -
                #   environment
         
     | 
| 
       343 
     | 
    
         
            -
                def change_env(env = false)
         
     | 
| 
       344 
     | 
    
         
            -
                  env = env.to_s.downcase
         
     | 
| 
       345 
     | 
    
         
            -
                  if env == 'production'
         
     | 
| 
       346 
     | 
    
         
            -
                    @env = 'production'
         
     | 
| 
       347 
     | 
    
         
            -
                  else
         
     | 
| 
       348 
     | 
    
         
            -
                    @env = 'development'
         
     | 
| 
       349 
     | 
    
         
            -
                    @env = Rails.env if defined?(Rails)
         
     | 
| 
       350 
     | 
    
         
            -
                  end
         
     | 
| 
       351 
     | 
    
         
            -
                  assign_endpoints
         
     | 
| 
       352 
     | 
    
         
            -
                end
         
     | 
| 
       353 
     | 
    
         
            -
             
     | 
| 
       354 
273 
     | 
    
         
             
                # Generates the appropriate IPN response depending on the status of the
         
     | 
| 
       355 
274 
     | 
    
         
             
                # transaction.
         
     | 
| 
       356 
275 
     | 
    
         
             
                #
         
     | 
| 
         @@ -393,9 +312,13 @@ module Pesapal 
     | 
|
| 
       393 
312 
     | 
    
         
             
                  status = query_payment_status(merchant_reference, transaction_tracking_id)
         
     | 
| 
       394 
313 
     | 
    
         
             
                  output = { status: status, response: nil }
         
     | 
| 
       395 
314 
     | 
    
         | 
| 
      
 315 
     | 
    
         
            +
                  response = "pesapal_notification_type=#{notification_type}"
         
     | 
| 
      
 316 
     | 
    
         
            +
                  response += "&pesapal_transaction_tracking_id=#{transaction_tracking_id}"
         
     | 
| 
      
 317 
     | 
    
         
            +
                  response += "&pesapal_merchant_reference=#{merchant_reference}"
         
     | 
| 
      
 318 
     | 
    
         
            +
             
     | 
| 
       396 
319 
     | 
    
         
             
                  case status
         
     | 
| 
       397 
     | 
    
         
            -
                  when 'COMPLETED' then output[:response] =  
     | 
| 
       398 
     | 
    
         
            -
                  when 'FAILED'    then output[:response] =  
     | 
| 
      
 320 
     | 
    
         
            +
                  when 'COMPLETED' then output[:response] = response
         
     | 
| 
      
 321 
     | 
    
         
            +
                  when 'FAILED'    then output[:response] = response
         
     | 
| 
       399 
322 
     | 
    
         
             
                  end
         
     | 
| 
       400 
323 
     | 
    
         | 
| 
       401 
324 
     | 
    
         
             
                  output
         
     | 
| 
         @@ -403,33 +326,24 @@ module Pesapal 
     | 
|
| 
       403 
326 
     | 
    
         | 
| 
       404 
327 
     | 
    
         
             
                private
         
     | 
| 
       405 
328 
     | 
    
         | 
| 
       406 
     | 
    
         
            -
                 
     | 
| 
       407 
     | 
    
         
            -
             
     | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
     | 
    
         
            -
                    @api_domain = 'https://www.pesapal.com'
         
     | 
| 
       410 
     | 
    
         
            -
                  else
         
     | 
| 
       411 
     | 
    
         
            -
                    @api_domain = 'https://demo.pesapal.com'
         
     | 
| 
       412 
     | 
    
         
            -
                  end
         
     | 
| 
       413 
     | 
    
         
            -
             
     | 
| 
       414 
     | 
    
         
            -
                  @api_endpoints = {}
         
     | 
| 
       415 
     | 
    
         
            -
                  @api_endpoints[:postpesapaldirectorderv4] = "#{@api_domain}/API/PostPesapalDirectOrderV4"
         
     | 
| 
       416 
     | 
    
         
            -
                  @api_endpoints[:querypaymentstatus] = "#{@api_domain}/API/QueryPaymentStatus"
         
     | 
| 
       417 
     | 
    
         
            -
                  @api_endpoints[:querypaymentdetails] = "#{@api_domain}/API/QueryPaymentDetails"
         
     | 
| 
      
 329 
     | 
    
         
            +
                def api_domain
         
     | 
| 
      
 330 
     | 
    
         
            +
                  @env == 'production' ? 'www.pesapal.com' : 'demo.pesapal.com'
         
     | 
| 
      
 331 
     | 
    
         
            +
                end
         
     | 
| 
       418 
332 
     | 
    
         | 
| 
       419 
     | 
    
         
            -
             
     | 
| 
      
 333 
     | 
    
         
            +
                def api_endpoint
         
     | 
| 
      
 334 
     | 
    
         
            +
                  'https://' + api_domain
         
     | 
| 
       420 
335 
     | 
    
         
             
                end
         
     | 
| 
       421 
336 
     | 
    
         | 
| 
       422 
     | 
    
         
            -
                 
     | 
| 
       423 
     | 
    
         
            -
             
     | 
| 
       424 
     | 
    
         
            -
                 
     | 
| 
       425 
     | 
    
         
            -
                  @config = { callback_url: 'http://0.0.0.0:3000/pesapal/callback',
         
     | 
| 
       426 
     | 
    
         
            -
                              consumer_key: '<YOUR_CONSUMER_KEY>',
         
     | 
| 
       427 
     | 
    
         
            -
                              consumer_secret: '<YOUR_CONSUMER_SECRET>'
         
     | 
| 
       428 
     | 
    
         
            -
                            }
         
     | 
| 
      
 337 
     | 
    
         
            +
                def postpesapaldirectorderv4_url
         
     | 
| 
      
 338 
     | 
    
         
            +
                  api_endpoint + '/API/PostPesapalDirectOrderV4'
         
     | 
| 
      
 339 
     | 
    
         
            +
                end
         
     | 
| 
       429 
340 
     | 
    
         | 
| 
       430 
     | 
    
         
            -
             
     | 
| 
      
 341 
     | 
    
         
            +
                def querypaymentstatus_url
         
     | 
| 
      
 342 
     | 
    
         
            +
                  api_endpoint + '/API/QueryPaymentStatus'
         
     | 
| 
      
 343 
     | 
    
         
            +
                end
         
     | 
| 
       431 
344 
     | 
    
         | 
| 
       432 
     | 
    
         
            -
             
     | 
| 
      
 345 
     | 
    
         
            +
                def querypaymentdetails_url
         
     | 
| 
      
 346 
     | 
    
         
            +
                  api_endpoint + '/API/QueryPaymentDetails'
         
     | 
| 
       433 
347 
     | 
    
         
             
                end
         
     | 
| 
       434 
348 
     | 
    
         
             
              end
         
     | 
| 
       435 
349 
     | 
    
         
             
            end
         
     |