|
| 1 | +# Payson API |
| 2 | + |
| 3 | +A simple utility to handle requests against the Payson payment gateway API. |
| 4 | + |
| 5 | +## Supported Ruby versions |
| 6 | + |
| 7 | +* 2.6 |
| 8 | +* 2.7 |
| 9 | +* 3.0 |
| 10 | + |
| 11 | +## Install |
| 12 | + |
| 13 | +Put this line in your Gemfile: |
| 14 | + |
| 15 | + gem 'payson_api' |
| 16 | + |
| 17 | +Then bundle: |
| 18 | + |
| 19 | + $ bundle |
| 20 | + |
| 21 | +## Usage (v2) |
| 22 | + |
| 23 | +This explains how to use this gem with the [Payson Checkout v2 API](https://tech.payson.se/paysoncheckout2). |
| 24 | + |
| 25 | +### General configuration options |
| 26 | + |
| 27 | +You need to configure the gem with your own Payson credentials through the `PaysonAPI::V2.configure` method: |
| 28 | + |
| 29 | +```ruby |
| 30 | +PaysonAPI::V2.configure do |config| |
| 31 | + config.api_user_id = 'XXXX' |
| 32 | + config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' |
| 33 | +end |
| 34 | +``` |
| 35 | + |
| 36 | +Please note that if `config.api_user_id` is set to 4, the client will go into test mode. Valid test access credentials could be found in their [documentation](https://tech.payson.se/#Testing/sandbox). |
| 37 | + |
| 38 | +For more detailed testing you may create your own test agent for use in the test environment. Use `config.test_mode = true` |
| 39 | + |
| 40 | +### Showing account info |
| 41 | + |
| 42 | +```ruby |
| 43 | +account = PaysonAPI::V2::Client.get_account |
| 44 | +``` |
| 45 | + |
| 46 | +### Creating a checkout |
| 47 | + |
| 48 | +```ruby |
| 49 | +request = PaysonAPI::V2::Requests::CreateCheckout.new |
| 50 | +request.merchant.checkout_uri = 'http://localhost/checkout' |
| 51 | +request.merchant.confirmation_uri = 'http://localhost/confirmation' |
| 52 | +request.merchant.notification_uri = 'http://localhost/notification' |
| 53 | +request.merchant.terms_uri = 'http://localhost/terms' |
| 54 | +request.order.currency = 'sek' |
| 55 | +request.order.items << PaysonAPI::V2::Requests::OrderItem.new.tap do |item| |
| 56 | + item.name = 'My product name' |
| 57 | + item.unit_price = 1000 |
| 58 | + item.quantity = 3 |
| 59 | + item.reference = 'product-1' |
| 60 | +end |
| 61 | +``` |
| 62 | + |
| 63 | +### Updating a checkout |
| 64 | + |
| 65 | +```ruby |
| 66 | +checkout = PaysonAPI::V2::Client.get_checkout(checkout_id) |
| 67 | + |
| 68 | +request = PaysonAPI::V2::Requests::UpdateCheckout.new |
| 69 | +request.id = checkout.id |
| 70 | +request.status = checkout.status |
| 71 | +request.merchant.checkout_uri = checkout.merchant.checkout_uri |
| 72 | +request.merchant.confirmation_uri = checkout.merchant.confirmation_uri |
| 73 | +request.merchant.notification_uri = checkout.merchant.notification_uri |
| 74 | +request.merchant.terms_uri = checkout.merchant.terms_uri |
| 75 | +request.order.currency = 'eur' |
| 76 | +request.order.items << PaysonAPI::V2::Requests::OrderItem.new.tap do |item| |
| 77 | + item.name = 'My product name' |
| 78 | + item.unit_price = 200 |
| 79 | + item.quantity = 3 |
| 80 | + item.reference = 'product-1' |
| 81 | +end |
| 82 | +request.order.items << PaysonAPI::V2::Requests::OrderItem.new.tap do |item| |
| 83 | + item.name = 'Another product name' |
| 84 | + item.unit_price = 600 |
| 85 | + item.quantity = 1 |
| 86 | + item.reference = 'product-2' |
| 87 | +end |
| 88 | + |
| 89 | +checkout = PaysonAPI::V2::Client.update_checkout(request) |
| 90 | +``` |
| 91 | + |
| 92 | +## Usage (v1) |
| 93 | + |
| 94 | +This explains how to use the [Payson 1.0 API](https://tech.payson.se/paysoncheckout1). |
| 95 | + |
| 96 | +### General configuration options |
| 97 | + |
| 98 | +You need to configure the gem with your own Payson credentials through the `PaysonAPI::V1.configure` method: |
| 99 | + |
| 100 | +```ruby |
| 101 | +PaysonAPI::V1.configure do |config| |
| 102 | + config.api_user_id = 'XXXX' |
| 103 | + config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' |
| 104 | +end |
| 105 | +``` |
| 106 | + |
| 107 | +Please note that if `config.api_user_id` is set to 4, the client will go into test mode. Valid test access credentials could be found in {documentation}[https://tech.payson.se/#Testing/sandbox]. |
| 108 | + |
| 109 | +For more detailed testing you may create your own test agent for use in the test environment. Use `config.test_mode = true` |
| 110 | + |
| 111 | +### Initiating a payment |
| 112 | + |
| 113 | +```ruby |
| 114 | +payment = PaysonAPI::V1::Requests::Payment.new |
| 115 | +payment.return_url = 'http://localhost/payson/success' |
| 116 | +payment.cancel_url = 'http://localhost/payson/cancel' |
| 117 | +payment.ipn_url = 'http://localhost/payson/ipn' |
| 118 | +payment.memo = 'Sample order description' |
| 119 | +payment.sender = sender |
| 120 | + |
| 121 | +payment.sender = PaysonAPI::V1::Sender.new.tap do |s| |
| 122 | + |
| 123 | + s.first_name = 'My' |
| 124 | + s.last_name = 'Customer' |
| 125 | +end |
| 126 | + |
| 127 | +payment.receivers = [] |
| 128 | +payment.receivers << PaysonAPI::V1::Receiver.new.tap do |r| |
| 129 | + |
| 130 | + r.amount = 100 |
| 131 | + r.first_name = 'Me' |
| 132 | + r.last_name = 'Just me' |
| 133 | + r.primary = true |
| 134 | +end |
| 135 | + |
| 136 | +payment.order_items = [] |
| 137 | +payment.order_items << PaysonAPI::V1::OrderItem.new.tap do |i| |
| 138 | + i.description = 'Order item description' |
| 139 | + i.unit_price = 100 |
| 140 | + i.quantity = 1 |
| 141 | + i.tax = 0 |
| 142 | + i.sku = 'MY-ITEM-1' |
| 143 | +end |
| 144 | + |
| 145 | +response = PaysonAPI::V1::Client.initiate_payment(payment) |
| 146 | + |
| 147 | +if response.success? |
| 148 | + # Redirect to response.forward_url |
| 149 | +else |
| 150 | + puts response.errors |
| 151 | +end |
| 152 | +``` |
| 153 | + |
| 154 | +### Requesting payment details |
| 155 | + |
| 156 | +```ruby |
| 157 | +token = 'token-received-from-payment-request' |
| 158 | + |
| 159 | +payment_details = PaysonAPI::V1::Requests::PaymentDetails.new(token) |
| 160 | + |
| 161 | +response = PaysonAPI::V1::Client.get_payment_details(payment_details) |
| 162 | + |
| 163 | +if response.success? |
| 164 | + # Do stuff with response object |
| 165 | +else |
| 166 | + puts response.errors |
| 167 | +end |
| 168 | +``` |
| 169 | + |
| 170 | +### Updating a payment |
| 171 | + |
| 172 | +```ruby |
| 173 | +token = 'token-received-from-payment-request' |
| 174 | +action = 'CANCELORDER' |
| 175 | + |
| 176 | +payment_update = PaysonAPI::V1::Requests::PaymentUpdate.new(token, action) |
| 177 | + |
| 178 | +response = PaysonAPI::V1::Client.update_payment(payment_update) |
| 179 | + |
| 180 | +if response.success? |
| 181 | + # Do stuff with response object |
| 182 | +else |
| 183 | + puts response.errors |
| 184 | +end |
| 185 | +``` |
| 186 | + |
| 187 | +### Validating an IPN response |
| 188 | + |
| 189 | +This example assumes the use of the Rails web framework. |
| 190 | + |
| 191 | +```ruby |
| 192 | +class Payson < ApplicationController |
| 193 | + def ipn_responder |
| 194 | + request_body = request.body.read |
| 195 | + ipn_response = PaysonAPI::V1::Responses::IPN.new(request_body) |
| 196 | + |
| 197 | + # Create a new IPN request object containing the raw response from above |
| 198 | + ipn_request = PaysonAPI::V1::Requests::IPN.new(ipn_response.raw) |
| 199 | + |
| 200 | + validate = PaysonAPI::V1::Client.validate_ipn(ipn_request) |
| 201 | + |
| 202 | + unless validate.verified? |
| 203 | + raise "Something went terribly wrong." |
| 204 | + end |
| 205 | + |
| 206 | + # Do business transactions, e.g. update the corresponding order: |
| 207 | + # order = Order.find_by_payson_token(ipn_response.token) |
| 208 | + # order.payson_status = ipn_response.status |
| 209 | + # order.save! |
| 210 | + end |
| 211 | +end |
| 212 | +``` |
| 213 | + |
| 214 | +## Todo |
| 215 | + |
| 216 | +Document the code for the Payson Checkout v2 processes. |
| 217 | + |
| 218 | +## Build Status |
| 219 | + |
| 220 | +[](https://travis-ci.org/stoffus/payson_api) |
| 221 | + |
| 222 | +## Questions, Feedback |
| 223 | + |
| 224 | +Feel free to message me on Github (stoffus). |
| 225 | + |
| 226 | +## Copyright |
| 227 | + |
| 228 | +Copyright (c) 2021 Christopher Svensson. |
0 commit comments