OnlinetoursGit/qiwi-pay

View on GitHub
README.md

Summary

Maintainability
Test Coverage
[![Build Status](https://travis-ci.org/OnlinetoursGit/qiwi-pay.svg?branch=master)](https://travis-ci.org/OnlinetoursGit/qiwi-pay)
[![Maintainability](https://api.codeclimate.com/v1/badges/eb4dda5c934aec79ef99/maintainability)](https://codeclimate.com/github/OnlinetoursGit/qiwi-pay/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/eb4dda5c934aec79ef99/test_coverage)](https://codeclimate.com/github/OnlinetoursGit/qiwi-pay/test_coverage)
[![Gem Version](https://badge.fury.io/rb/qiwi-pay.svg)](https://badge.fury.io/rb/qiwi-pay)

# QiwiPay

QiwiPay WPF/API binding for Ruby.

Provides support for payment operations using QiwiPay WPF and API services.

See [Official QiwiPay documentation](https://developer.qiwi.com/ru/qiwipay) for detailed API description.

## Table of contents

  *  [Installation](#installation)
  *  [Usage](#usage)
      * [Prepare credentials object](#prepare-credentials-object)
      * [Create cheque object](#create-cheque-object)
      * [Perform payment operations using WPF](#perform-payment-operations-using-wpf)
      * [Process QiwiPay confirmation callback](#process-qiwipay-confirmation-callback)
      * [Perform payment operations using JSON API](#perform-payment-operations-using-json-api)
  * [Development](#development)
  * [Contributing](#contributing)

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'qiwi-pay'
```

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install qiwi-pay


## Usage

There are three types of interactions with QiwiPay service:

1. Performing Web Payment Form requests
2. Performing JSON API requests
3. Handling callback confirmation requests

### Prepare credentials object
To perform any request you must provide your QiwiPay credentials. For doing that the `Credentials` object should be used.

```ruby
# Create credentials object
# You can use PKCS#12 container
p12 = OpenSSL::PKCS12.new(File.read('qiwi.p12'))

crds = QiwiPay::Credentials.new secret: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
                                p12: p12

# ... or provide certificate and key objects explicitly
crds = QiwiPay::Credentials.new secret: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
                                cert: p12.certificate,
                                key: p12.key

# ... or load from separate files
crds = QiwiPay::Credentials.new secret: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
                                cert: 'my.crt',
                                key: 'my.key'
```

### Create cheque object

See [Cheque section of Official QiwiPay documentation](https://developer.qiwi.com/ru/qiwipay/index.html?json#cheque) for details.
```ruby
cheque = QiwiPay::Cheque.new seller_id:        12345678901,
                             cheque_type:      QiwiPay::Cheque::Type::INFLOW,
                             customer_contact: 'client@example.com',
                             tax_system:       QiwiPay::Cheque::TaxMode::USN_DR,
                             positions: [{
                                quantity:    1,
                                price:       10_000,
                                tax:         QiwiPay::Cheque::VAT::NONE,
                                description: 'Order #1234 payment'
                             }]
```

### Perform payment operations using WPF
Only two types of payment operations are available for now:
* *sale* - single-step payment operation
* *auth* - initiate multi-steps payment operation

Operations are used in very similar way. Use `QiwiPay::Wpf::SaleOperation` class for *sale* operation and `QiwiPay::Wpf::AuthOperation` class for *auth* operation.

See [WPF section of Official QiwiPay documentation](https://developer.qiwi.com/ru/qiwipay/index.html?json#qiwipay-wpf) for details.

#### Create payment operation object
```ruby
op = QiwiPay::Wpf::SaleOperation.new crds,
                                     merchant_site: 111_111,
                                     currency: 643,
                                     email: 'client@example.com',
                                     country: 'RUS',
                                     city: 'Moscow',
                                     amount: 10_000,
                                     order_id: 1234,
                                     product_name: 'Flowers',
                                     merchant_uid: 432101,
                                     order_expire: Time.now + 3600,
                                     callback_url: 'https://example.com/payment/callback'
op.cheque = cheque
```

#### Build redirection URL for sale operation form
```ruby
op.url
=> 'https://pay.qiwi.com/paypage/initial?opcode=1&merchant_site=111111&currency=643&amount=1000.00&order_id=1234&email=client@example.com&country=RUS&city=Moscow&product_name=%D0%9E%D0%BF%D0%BB%D0%B0%D1%82%D0%B0+%D1%82%D1%83%D1%80%D0%B0&merchant_uid=432101&callback_url=https%3A%2F%example.com%2Fpayment%2Fcallback&sign=...c4dbf...'
```

#### Build form params WPF sale operation
This may be useful if you would like to construct redirection URL or invisible payment form by yourself.
```ruby
op.params
=> {:method=>:get,
 :url=>"https://pay.qiwi.com/paypage/initial",
 :opcode=>"1",
 :merchant_site=>"111111",
 :currency=>"643",
 :amount=>"1000.00",
 :order_id=>"1234",
 :email=>"client@example.com",
 :country=>"RUS",
 :city=>"Moscow",
 :product_name=>"Flowers",
 :merchant_uid=>"432101",
 :callback_url=>"https://example.com/payment/callback",
 :sign=>"...c4dbf..."}
```

### Process QiwiPay confirmation callback
After payment operation has been finished you will receive a confirmation callback request from Qiwi service. Use the request's (`ActionDispatch::Request`, `Rack::Request` or whatever it is) parameters hash to build `QiwiPay::Confirmation` object.

```ruby
conf = QiwiPay::Confirmation.new crds, request.params
```

Now you have a seamless way to access confirmation data and perform some tests on it.

```ruby
# Check if ip address is a valid Qiwi server address
conf.valid_server_ip? request.ip
=> true

# Check signature
conf.valid_sign?
=> true

# Read confirmation data
conf.txn_id
=> 11728960050

conf.order_id
=> 1234

conf.error_code
=> 0

conf.error_message
=> "No error"

conf.error?
=> false

conf.txn_status_message
=> "Authorized"

conf.txn_type_message
=> "Purchase: auth"

# Check if transaction was successful (valid signature and no error)
conf.success?
=> true

# Get all confirmation data as a hash
conf.to_h
=> {:txn_id=>11728960050,
 :txn_status=>2,
 :txn_type=>1,
 :txn_date=>"2018-05-03T15:55:18+00:00",
 :error_code=>0,
 :pan=>"510000******0082",
 :amount=>"10000.00",
 :currency=>643,
 :auth_code=>nil,
 :eci=>nil,
 :card_name=>nil,
 :card_bank=>nil,
 :order_id=>1234,
 :ip=>"196.54.55.20",
 :email=>"client@example.com",
 :country=>"RUS",
 :city=>"Moscow",
 :region=>nil,
 :address=>nil,
 :phone=>nil,
 :cf1=>nil,
 :cf2=>nil,
 :cf3=>nil,
 :cf4=>nil,
 :cf5=>nil,
 :product_name=>"Flowers",
 :card_token=>nil,
 :card_token_expire=>nil,
 :sign=>"27A56431CD3A14BA34...8A",
 :txn_status_message=>"Authorized",
 :txn_type_message=>"Single-step purchase"}
```

### Perform payment operations using JSON API
Following operations are available for now:

* *capture* - `QiwiPay::Api::CaptureOperation` class
* *refund* - `QiwiPay::Api::RefundOperation` class
* *reversal* - `QiwiPay::Api::ReversalOperation` class
* *status* - `QiwiPay::Api::StatusOperation` class

#### Status operation
##### Create and perform `status` operation object
```ruby
op = QiwiPay::Api::StatusOperation.new crds,
                                       merchant_site: 111111,
                                       txn_id: 11728960050,
                                       order_id: 1234
response = op.perform
```

Operations' `perform` methods return `QiwiPay::Api::Response` object. It allow you to get text messages for errors, codes and statuses. See [Transaction statuses section of Official QiwiPay documentation](https://developer.qiwi.com/ru/qiwipay/index.html?json#txn_status)

In case the JSON API response parsing fails, the whole response body is returned by `Response`'s `error_message` method and the `error_code` is set to -1.

##### Operation succeeded
```ruby
response.success?
=> true
response.error_code
=> 0
response.error_message
=> "No errors"
```

##### Operation failed
```ruby
response.success?
=> false
response.http_code
=> 200
response.error_code
=> 8021
response.error_message
=> "Merchant site not found"
```

#### Refund/reversal operation
Both operations are performed in the same way, just use the right class.

```ruby
op = QiwiPay::Api::RefundOperation.new crds,
                                       merchant_site: 111111,
                                       txn_id: 11728960050,
                                       amount: 500,
                                       cheque: cheque
response = op.perform
=> #<QiwiPay::Api::Response http_code=200 error_code=8018 ...>
response.success?
=> false
response.http_code
=> 200
response.error_code
=> 8018
response.error_message
=> "Parsing error"
response.to_h
=> {:request_id => "01234567-89ab-cdef-0123-456789abcdef",
 :error_message => "Parsing error",
 :error_code => 8018,
 :http_code => 200
}
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` or `rake console` or `rake c` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/OnlinetoursGit/qiwi-pay.