Skip to content

PSCB bank payment service integration / Интеграция с ПСКБ-эквайрингом

License

Notifications You must be signed in to change notification settings

holyketzer/pscb_integration

Repository files navigation

Gem Version Build Status Code Climate Test Coverage

PSCB Integration

PSCB bank payment service integration (trade acquiring).

Official documentation http://docs.pscb.ru/oos/

Offer https://pscb.ru/corp/services/payment_service/platezhi-v-internete/.

Disclamer

Stay awhile and listen. Are you sure that you need this stuff?

Pro:

  • 3% fee for Visa/MasterCard payments

Cons:

  • During 1.5 years of our expirience PSCB lost all client's reccurent bingings twice. We lost a lot of revenue because of this.
  • Very slow personal account web site, it takes tens of seconds to load a page.
  • API looks not solid and have a lack of consistency, it has several ways to return errors in response
  • PSCB send demo environment payment callbacks to your production server, and if you don't handle them, they send you email like 'We have got invalid response for our HTTP-callbacks', so they can't completely split demo and production environments

Your choise

It's up to you. Probably Yandex.Kassa will be better option, its API looks much more solid and reliable (it's Yandex anyway) but it has higher fee 3.5% on base plan for bank cards. But if you revenue more than 1 million RUB per month then only 2.8%. I suppose the choice is obvious here.

Installation

I see you decided to try. Good luck and best wishes.

Add this line to your application's Gemfile:

gem 'pscb_integration'

And then execute:

$ bundle

Usage

Configuration

Configure it in <you app folder>/config/initializers/pscb.rb with:

PscbIntegration.setup do |config|
  config.host = 'https://oos.pscb.ru'
  config.market_place = '<your market place id>'
  config.secret_key = '<your secret key>'
  config.demo_secret_key = '<your secret key for demo env>'
  config.confirm_payment_callback = PaymentService.method(:confirm_pscb_payment_callback)
end

If your application didn't setup PscbIntegration configuration with setup block then PscbIntegration::ConfigurationError will be raised during first attempt to call of any method.

Handling payment status notification

Mount engine in your routes.rb file as you wish, e.g.:

namespace :integration_api do
  mount PscbIntegration::Engine => '/'
end

Implement callback function assigned to confirm_pscb_payment_callback:

Arguments: payment - hash with payment details from PSCB:

Property Description
orderId Unique order id generated by merchant
showOrderId Not uniqe order id generated by merchant to show it to customer
paymentId Order id generated by PSCB
account Customer id on merchant side
marketPlace Merchant id on PSCB side
paymentMethod Payment method
state Payment state
stateDate Date of last state changing ISO8601
amount Order amount
recurrencyToken Recurrency token

is_demo - if true then payment is from demo environment else from production.

Callback should return true if you system accepts and confirms payment, and false (nil) in case of rejecting. Example:

def confirm_pscb_payment_callback(payment, is_demo)
  if (order = OrderModel.find_by(uid: payment['orderId']))
    # Some state machine transition
    order.apply_status(payment['state'])
  end
end

Build payment url

PSCB API documentation

client = PscbIntegration::Client.new

url = client.build_payment_url(
  nonce: SecureRandom.hex(5), # Salt to avoid replay attack
  customerAccount: user.id, # Some user id
  customerRating: 5, # Customer rating 
  customerEmail: user.email, # Customer email
  customerPhone: user.phone, # Customer phone
  orderId: '123456', # Unique order id
  details: 'Some paymnet', # Payment details comment
  amount: 500, # Amount in RUB
  paymentMethod: 'ac', # Payment menthod
  recurrentable: true, # Payment can be repeated by merchant
  data: {
    debug: 1, # show debug info in customer browser 
  }
)

Pull order status

PSCB API documentation

Client methods return result in Either monad for helping handling errors on different level. Thank you @bolshakov.

How it works:

  • Right result means success
  • Left result means PSCB returns some conscious error which can require special handling on our side.
  • any exception means unexpected error (e.g. timeout, network) that we don't know how to handle, and probably best option is to log it and try again later.

Learn more about Either monad usage. Example:

client = PscbIntegration::Client.new

res = client.pull_order_status(order.id)

res.reduce(
  # Left result is handled here
  # @param error - PscbIntegration::BaseApiError
  ->(error) {
    # Some special error handling e.g.
    if error.unknown_payment?
      # Do something special
    end
  },

  # Right result is handled here
  # @param payment - payment hash from PSCB
  ->(payment) { 
    # Update order status
  }
)

Recurring payment

PSCB API documentation

Before this call you customer should successefully paid order with recurrentable flag. In callback or through status pulling recurrency_token will be returned.

client = PscbIntegration::Client.new

res = client.recurring_payment(
    prev_order_uid: prev_order.id, # Previous recurrentable order id
    new_order_uid: new_order.id, # New order id
    token: recurrency_token, # Recurrency token from previous order 
    amount: 300, # Amount in RUB
)

res.reduce(
  ->(error) { },
  ->(payment) { },
)

Refund order

PSCB API documentation

client = PscbIntegration::Client.new

res = client.refund_order(order.id)

res.reduce(
  ->(error) { },
  ->(payment) { },
)

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 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.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/holyketzer/pscb_integration.

License

The gem is available as open source under the terms of the MIT License.