Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
This is a copy of the original gem openpay but the version 3 is not released yet, in this version is enable the use for different countries, I've tested some functionalities and it works fine, be careful with its use.
ruby client for Openpay api services (version 3.0.0)
This is a ruby client implementing the payment services for Openpay at openpay.mx
For more information about Openpay visit:
For the full Openpay api documentation take a look at:
Add the following line to your Gem file
#openpay gem
gem 'openpay'
Update your bundle:
$ bundle
Or install it from the command line:
$ gem install openpay
* ruby 2.4 or higher
require 'openpay'
#merchant and private key
merchant_id = 'mywvupjjs9xdnryxtplq'
private_key = 'sk_92b25d3baec149e6b428d81abfe37006'
country = 'mx'
#An openpay resource factory instance is created out of the OpenpayApi
#it points to the development environment by default.
#The country value can take 'mx' to Mexico or 'co' for Colombia
openpay = OpenpayApi.new(merchant_id, private_key, country)
#To enable production mode you should pass a third argument as true.
#openpay_prod=OpenpayApi.new(merchant_id,private_key,true)
#This ruby client manages a default timeout of 90 seconds to make the request
# to Openpay services, if you need to modify this value, you need to explicitly
# define the type of environment and followed by the new value for the timeout.
#Syntax:
# openpay_prod=OpenpayApi.new(merchant_id,private_key,isProduction,timeout)
#Example:
# openpay_prod=OpenpayApi.new(merchant_id,private_key,false,30)
The openpay factory instance is in charge to generate the required resources through a factory method (create). Resource classes should be initialized using the factory method as described below.
#creating an instance for each available resource
bankaccounts = openpay.create(:bankaccounts)
cards = openpay.create(:cards)
charges = openpay.create(:charges)
customers = openpay.create(:customers)
fees = openpay.create(:fees)
payouts = openpay.create(:payouts)
plans = openpay.create(:plans)
subscriptions = openpay.create(:subscriptions)
transfers = openpay.create(:transfers)
According to the current version of the Openpay api the available resources are:
Each rest resource exposed in the rest Openpay api is represented by a class in this ruby API, being ** OpenpayResource** the base class.
Each resource depending of its structure and available methods, will have one or more of the methods described under the methods subsection. Below a short description about the implementation high level details. For detailed documentation take a look a the openpay api documentation.
Given most resources belong, either to a merchant or a customer, the api was designed taking this in consideration, so:
The first argument represent the json/hash object, while the second argument which is optional represents the ** customer_id**. So if just one argument is provided the action will be performed at the merchant level, but if the second argument is provided passing the customer_id, the action will be performed at the customer level.
The following illustrates the api design.
#Merchant
hash_out = open_pay_resource.create(hash_in)
json_out = open_pay_resource.create(json_in)
#Customer
hash_out = open_pay_resource.create(hash_in, customer_id)
json_out = open_pay_resource.create(json_in, customer_id)
This api supports both ruby hashes and json strings as inputs and outputs. (See previous example) If a ruby hash is passed in as in input, a hash will be returned as the method output. if a json string is passed in as an input, a json string will be returned as the method function output.
This code excerpt from a specification demonstrates how you can use hashes and json strings interchangeably.
Methods without inputs will return a ruby hash.
it 'creates a fee using a json message' do
#create new customer
customer_hash = FactoryBot.build(:customer)
customer = @customers.create(customer_hash)
#create customer card , using factory girl to build the hash for us
card_hash = FactoryBot.build(:valid_card)
card = @cards.create(card_hash, customer['id'])
#create charge
charge_hash = FactoryBot.build(:card_charge, source_id: card['id'], order_id: card['id'], amount: 4000)
charge = @charges.create(charge_hash, customer['id'])
#create customer fee , using json as input, we get json as ouput
fee_json = %^{"customer_id":"#{customer['id']}","amount":"12.50","description":"Cobro de Comisión"}^
expect(@fees.create(fee_json)).to have_json_path('amount')
end
Here you can see how the card_hash representation looks like.
require 'pp'
pp card_hash =>
{ :bank_name => "visa",
:holder_name => "Vicente Olmos",
:expiration_month => "09",
:card_number => "4111111111111111",
:expiration_year => "14",
:bank_code => "bmx",
:cvv2 => "111",
:address =>
{ :postal_code => "76190",
:state => "QRO",
:line1 => "LINE1",
:line2 => "LINE2",
:line3 => "LINE3",
:country_code => "MX",
:city => "Queretaro" } }
Next, how we construct the preceding hash using FactoryBot. FactoryBot was used in our test suite to facilitate hash construction. It may help you as well at your final implementation if you decide to use hashes. (more examples at test/Factories.rb)
FactoryBot.define do
factory :valid_card, class: Hash do
bank_name 'visa'
holder_name 'Vicente Olmos'
expiration_month '09'
card_number '4111111111111111'
expiration_year '14'
bank_code 'bmx'
cvv2 '111'
address { {
postal_code: '76190',
state: 'QRO',
line1: 'LINE1',
line2: 'LINE2',
line3: 'LINE3',
country_code: 'MX',
city: 'Queretaro',
} }
initialize_with { attributes }
end
This ruby API standardize the method names across all different resources using the create,get,update and ** delete** verbs.
For full method documentation take a look at:
The test suite at test/spec is a good source of reference.
Creates the given resource
open_pay_resource.create(representation, customer_id = nil)
Gets an instance of a given resource
open_pay_resource.get(object_id, customer_id = nil)
Updates an instance of a given resource
open_pay_resource.update(representation, customer_id = nil)
Deletes an instance of the given resource
open_pay_resource.delete(object_id, customer_id = nil)
Returns an array of all instances of a resource
open_pay_resource.all(customer_id = nil)
Returns a block for each instance resource
open_pay_resource.each(customer_id = nil)
Deletes all instances of the given resource
#in case this method is executed under the production environment an OpenpayException will be raised.
open_pay_resource.delete_all(customer_id = nil)
creates a merchant bank account , is not supported through the API, use the console instead.
creates a customer bank account
bank_accounts.create(account_hash,customer_id)
get a given bank account for a given customer
bank_account=bank_accounts.get(customer_id,bankaccount_id)
each customer bank account
bank_accounts.each(customer_id) do |bank_account|
bank_account['alias']
end
list merchant / customer bank accounts
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = bank_accounts.list(search_params)
customer_filtered_list = bank_accounts.list(search_params, customer_id)
all bank accounts for a given customer
accounts=bank_accounts.all(customer_id)
deletes a given customer bank account
bank_accounts.delete(customer_id,bank_id)
deletes all customer bank accounts (sandbox mode only)
bank_accounts.delete_all(customer['id'])
creates a merchant card
cards.create(card_json)
creates a customer card
cards.create(card_hash, customer_id)
gets merchant card
card=cards.get(card_id)
gets customer card
card=cards.get(card_id, customer_id)
each merchant card
cards.each {|merchant_card| p card}
list merchant / customer cards
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = cards.list(search_params)
customer_filtered_list = cards.list(search_params, customer_id)
each customer card
cards.each(customer_id) {|customer_card | p customer_card }
all merchant cards
merchant_cards=cards.all
all customer cards
customer_cards=cards.all(customer_id)
delete merchant card
cards.delete(card_id)
delete customer card
cards.delete(card_id,customer_id)
delete all merchant cards
cards.delete_all
delete all customer cards
cards.delete_all(customer_id)
creates merchant charge
charges.create(charge_hash)
creates customer charge
charges.create(charge_hash,customer_id)
gets merchant charge
merchant_charge=charges.get(charge_id)
gets customer charge
customer_charge=charges.get(charge_id,customer_id)
each merchant charge
charges.each {|charge| p charge}
list merchant / customer charges
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = charges.list(search_params)
customer_filtered_list = charges.list(search_params, customer_id)
each customer charge
charges.each(customer_id) {|charge| p charge}
all merchant charge
charges.all
all customer charge
charges.all(customer_id)
capture merchant card
charges.capture(charge_id)
capture customer card
charges.capture(charge['id'],customer['id'])
confirm capture merchant
#pass a hash with the following options, no customer_id needed
confirm_capture_options = { transaction_id: transaction['id'], amount: 100 }
charges.confirm_capture(confirm_capture_options)
confirm capture customer
#pass a hash with the following options, pass the customer_id
confirm_capture_options = { customer_id: customer['id'], transaction_id: charge['id'], amount: 100 }
charges.confirm_capture(confirm_capture_options)
refund merchant charge
charges.refund(charge_id, refund_description_hash)
refund merchant charge
charges.refund(charge_id, refund_description_hash)
creates customer
customers.create(customer_json)
get customer
customer=customers.get(customer_id)
update customer
customers.update(customer_hash)
delete customer
customers.delete(customer_id)
each customer
customers.each do {|customer| p customer }
list customers
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
customers_filtered_list = customers.list(search_params)
all customer
all_customers=customers.all
delete all customers (sand box mode only)
all_customers=customers.all
creates fee
#In order to create a fee a charge should exists
fee.create(fee_hash)
gets all fees
all_fees=fees.all
list customer fees
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = fees.list(search_params)
creates a merchant payout
payouts.create(payout_json)
creates a customer payout
payouts.create(payout_hash,customer_id)
gets a merchant payout
payouts.get(payout_id)
gets a customer payout
payouts.get(payout_id,customer_id)
all merchant payouts
merchant_payouts=payouts.all
all customer payouts
customer_payouts=payouts.all(customer_id)
each merchant payout
payouts.each { |payout| p payout }
each customer payout
payouts.each(customer_id) { |payout| p payout }
list merchant/customer payouts
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = payouts.list(search_params)
customer_filtered_list = payouts.list(search_params, customer_id)
create merchant plan
plans.create(plan_hash)
create customer plan
plans.create(plan_hash,customer_id)
get a merchant plan
merchant_plan=plans.get(plan_id)
get a customer plan
customer_plan=plans.get(plan_id,customer_id)
updates a merchant plan
plans.update(plan_hash,customer_id)
updates a customer plan
plans.update(plan_hash,customer_id)
each merchant plan
plans.each do {|plan| p plan }
each customer plans
plans.each(customer_id) do {|plan| p plan }
list merchant /customer plan
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = plans.list(search_params)
customer_filtered_list = plans.list(search_params, customer_id)
all merchant plans
plans.all
all customer plans
plans.all(customer_id)
create customer subscriptions
subscriptions.create(subscriptions_hash,customer_id)
get customer subscription
subscriptions.get(subscriptions_hash,customer_id)
update customer subscription
subscription_update_hash={ trial_end_date: "2016-01-12" }
subscriptions.update(subscription_id,customer_id, subscription_update_hash )
all customer subscription
subscriptions.all(customer_id)
each customer subscription
subscriptions.each(customer_id) {|subscription| p subscription }
list customer subscriptions
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
customer_filtered_list = subscriptions.list(search_params, customer_id)
deletes customer subscription
subscriptions.delete(customer_id)
deletes all customer subscriptions ( sandbox mode only)
subscriptions.delete(customer_id)
create transfer
transfers.create(transfer_hash,customer_id)
get transfer
transfers.get(transfer_id,customer_id)
all customer transfers
transfers.all(customer_id)
each customer transfer
transfers.each(customer_id) {|transfer| p transfer }
list customer transfers
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
customer_filtered_list = transfers.list(search_params, customer_id)
This API generates 3 different Exception classes.
OpenpayException: Generic base API exception class, Generic API exceptions.
Internal server error (500 Internal Server Error).
OpenpayApi factory method, invalid resource name.
Examples:
#production mode
openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
customers = openpay_prod.create(:customers)
customers.delete_all # will raise an OpenpayException
#production mode
openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
customers = openpay_prod.create(:non_existing_resource) # will raise an OpenpayException
OpenpayConnectionException: Exception class for connection related issues, errors happening prior the server connection.
Authentication Error (401 Unauthorized)
Connection Errors.
SSL Errors.
Example:
#invalid id and key
merchant_id='santa'
private_key='invalid'
openpay=OpenpayApi.new(merchant_id, private_key)
customers=openpay.create(:customers)
begin
customers.get('23444422211')
rescue OpenpayConnectionException => e
e.http_code # => 401
e.error_code # => 1002
e.description# => 'The api key or merchant id are invalid.'
e.json_body # {"category":"request","description":"The api key or merchant id are invalid.","http_code":401,"error_code":1002,"request_id":null}
end
OpenpayTransactionException: Errors happening after the initial connection has been initiated, errors during transactions.
Bad Request Example:
email = 'foo'
customer_hash = FactoryBot.build(:customer, email: email)
begin
customers.create(customer_hash)
rescue OpenpayTransactionException => e
e.http_code # => 400
e.error_code # => 1001
e.description # => 'email\' not a well-formed email address'
end
Resource not found Example:
begin
#non existing customer
customers.delete('1111')
rescue OpenpayApiTransactionError => e
e.http_code # => 404
e.error_code # =>1005
e.description # =>"The customer with id '1111' does not exist"
end
For more information about categories, descriptions and codes take a look at:
In the Openpay dashboard you are able to see every request and its corresponding request/response.
For more use cases take a look at the test/spec folder
ruby client for Openpay api services (version 3.0.0)
This is a ruby client implementing the payment services for Openpay at openpay.co
For more information about Openpay visit:
For the full Openpay api documentation take a look at:
Add the following line to your Gem file
#openpay gem
gem 'openpay'
Update your bundle:
$ bundle
Or install it from the command line:
$ gem install openpay
* ruby 2.4 or higher
require 'openpay'
#merchant and private key
merchant_id = 'mywvupjjs9xdnryxtplq'
private_key = 'sk_92b25d3baec149e6b428d81abfe37006'
country = 'co'
#An openpay resource factory instance is created out of the OpenpayApi
#it points to the development environment by default.
#The country value can take 'mx' to Mexico or 'co' for Colombia
openpay = OpenpayApi.new(merchant_id, private_key, country)
#To enable production mode you should pass a third argument as true.
#openpay_prod=OpenpayApi.new(merchant_id,private_key,true)
#This ruby client manages a default timeout of 90 seconds to make the request
# to Openpay services, if you need to modify this value, you need to explicitly
# define the type of environment and followed by the new value for the timeout.
#Syntax:
# openpay_prod=OpenpayApi.new(merchant_id,private_key,isProduction,timeout)
#Example:
# openpay_prod=OpenpayApi.new(merchant_id,private_key,false,30)
The openpay factory instance is in charge to generate the required resources through a factory method (create). Resource classes should be initialized using the factory method as described below.
#creating an instance for each available resource
cards = openpay.create(:cards)
charges = openpay.create(:charges)
customers = openpay.create(:customers)
plans = openpay.create(:plans)
subscriptions = openpay.create(:subscriptions)
transfers = openpay.create(:transfers)
pse = openpay.create(:pse)
According to the current version of the Openpay api the available resources are:
Each rest resource exposed in the rest Openpay api is represented by a class in this ruby API, being ** OpenpayResource** the base class.
Each resource depending of its structure and available methods, will have one or more of the methods described under the methods subsection. Below a short description about the implementation high level details. For detailed documentation take a look a the openpay api documentation.
Given most resources belong, either to a merchant or a customer, the api was designed taking this in consideration, so:
The first argument represent the json/hash object, while the second argument which is optional represents the ** customer_id**. So if just one argument is provided the action will be performed at the merchant level, but if the second argument is provided passing the customer_id, the action will be performed at the customer level.
The following illustrates the api design.
#Merchant
hash_out = open_pay_resource.create(hash_in)
json_out = open_pay_resource.create(json_in)
#Customer
hash_out = open_pay_resource.create(hash_in, customer_id)
json_out = open_pay_resource.create(json_in, customer_id)
This api supports both ruby hashes and json strings as inputs and outputs. (See previous example) If a ruby hash is passed in as in input, a hash will be returned as the method output. if a json string is passed in as an input, a json string will be returned as the method function output.
This code excerpt from a specification demonstrates how you can use hashes and json strings interchangeably.
Methods without inputs will return a ruby hash.
it 'creates a fee using a json message' do
#create new customer
customer_hash = FactoryBot.build(:customer_col)
customer = @customers.create(customer_hash)
#create customer card , using factory girl to build the hash for us
card_hash = FactoryBot.build(:valid_card_col)
card = @cards.create(card_hash, customer['id'])
#create charge
charge_hash = FactoryBot.build(:card_charge_col, source_id: card['id'], order_id: card['id'], amount: 4000)
charge = @charges.create(charge_hash, customer['id'])
end
Here you can see how the card_hash representation looks like.
require 'pp'
pp card_hash =>
{ :holder_name => 'Vicente Olmos',
:card_number => '4111111111111111',
:cvv2 => '111',
:expiration_month => '09',
:expiration_year => '25' }
Next, how we construct the preceding hash using FactoryBot. FactoryBot was used in our test suite to facilitate hash construction. It may help you as well at your final implementation if you decide to use hashes. (more examples at test/Factories.rb)
FactoryBot.define do
factory :valid_card_col, class: Hash do
holder_name 'Vicente Olmos'
expiration_month '09'
card_number '4111111111111111'
expiration_year '14'
cvv2 '111'
initialize_with { attributes }
end
This ruby API standardize the method names across all different resources using the create,get,update and ** delete** verbs.
For full method documentation take a look at:
The test suite at test/spec is a good source of reference.
Creates the given resource
open_pay_resource.create(representation, customer_id = nil)
Gets an instance of a given resource
open_pay_resource.get(object_id, customer_id = nil)
Updates an instance of a given resource
open_pay_resource.update(representation, customer_id = nil)
Deletes an instance of the given resource
open_pay_resource.delete(object_id, customer_id = nil)
Returns an array of all instances of a resource
open_pay_resource.all(customer_id = nil)
Returns a block for each instance resource
open_pay_resource.each(customer_id = nil)
Deletes all instances of the given resource
#in case this method is executed under the production environment an OpenpayException will be raised.
open_pay_resource.delete_all(customer_id = nil)
creates a merchant pse
pse.create(pse_hash)
creates a customer pse
pse.create(charge_hash,customer_id)
creates a merchant card
cards.create(card_json)
creates a customer card
cards.create(card_hash, customer_id)
gets merchant card
card=cards.get(card_id)
gets customer card
card=cards.get(card_id, customer_id)
each merchant card
cards.each {|merchant_card| p card}
list merchant / customer cards
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = cards.list(search_params)
customer_filtered_list = cards.list(search_params, customer_id)
each customer card
cards.each(customer_id) {|customer_card | p customer_card }
all merchant cards
merchant_cards=cards.all
all customer cards
customer_cards=cards.all(customer_id)
delete merchant card
cards.delete(card_id)
delete customer card
cards.delete(card_id,customer_id)
delete all merchant cards
cards.delete_all
delete all customer cards
cards.delete_all(customer_id)
creates merchant charge
charges.create(charge_hash)
creates customer charge
charges.create(charge_hash,customer_id)
gets merchant charge
merchant_charge=charges.get(charge_id)
gets customer charge
customer_charge=charges.get(charge_id,customer_id)
each merchant charge
charges.each {|charge| p charge}
list merchant / customer charges
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = charges.list(search_params)
customer_filtered_list = charges.list(search_params, customer_id)
each customer charge
charges.each(customer_id) {|charge| p charge}
all merchant charge
charges.all
all customer charge
charges.all(customer_id)
refund merchant charge
charges.refund(charge_id, refund_description_hash)
refund merchant charge
charges.refund(charge_id, refund_description_hash)
creates customer
customers.create(customer_json)
get customer
customer=customers.get(customer_id)
update customer
customers.update(customer_hash)
delete customer
customers.delete(customer_id)
each customer
customers.each do {|customer| p customer }
list customers
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
customers_filtered_list = customers.list(search_params)
all customer
all_customers=customers.all
delete all customers (sand box mode only)
all_customers=customers.all
create merchant plan
plans.create(plan_hash)
create customer plan
plans.create(plan_hash,customer_id)
get a merchant plan
merchant_plan=plans.get(plan_id)
get a customer plan
customer_plan=plans.get(plan_id,customer_id)
updates a merchant plan
plans.update(plan_hash,customer_id)
updates a customer plan
plans.update(plan_hash,customer_id)
each merchant plan
plans.each do {|plan| p plan }
each customer plans
plans.each(customer_id) do {|plan| p plan }
list merchant /customer plan
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = plans.list(search_params)
customer_filtered_list = plans.list(search_params, customer_id)
all merchant plans
plans.all
all customer plans
plans.all(customer_id)
create customer subscriptions
subscriptions.create(subscriptions_hash,customer_id)
get customer subscription
subscriptions.get(subscriptions_hash,customer_id)
update customer subscription
subscription_update_hash={ trial_end_date: "2016-01-12" }
subscriptions.update(subscription_id,customer_id, subscription_update_hash )
all customer subscription
subscriptions.all(customer_id)
each customer subscription
subscriptions.each(customer_id) {|subscription| p subscription }
list customer subscriptions
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
customer_filtered_list = subscriptions.list(search_params, customer_id)
deletes customer subscription
subscriptions.delete(customer_id)
deletes all customer subscriptions ( sandbox mode only)
subscriptions.delete(customer_id)
This API generates 3 different Exception classes.
OpenpayException: Generic base API exception class, Generic API exceptions.
Internal server error (500 Internal Server Error).
OpenpayApi factory method, invalid resource name.
Examples:
#production mode
openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
customers = openpay_prod.create(:customers)
customers.delete_all # will raise an OpenpayException
#production mode
openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
customers = openpay_prod.create(:non_existing_resource) # will raise an OpenpayException
OpenpayConnectionException: Exception class for connection related issues, errors happening prior the server connection.
Authentication Error (401 Unauthorized)
Connection Errors.
SSL Errors.
Example:
#invalid id and key
merchant_id = 'santa'
private_key = 'invalid'
openpay = OpenpayApi.new(merchant_id, private_key)
customers = openpay.create(:customers)
begin
customers.get('23444422211')
rescue OpenpayConnectionException => e
e.http_code # => 401
e.error_code # => 1002
e.description # => 'The api key or merchant id are invalid.'
e.json_body # {"category":"request","description":"The api key or merchant id are invalid.","http_code":401,"error_code":1002,"request_id":null}
end
OpenpayTransactionException: Errors happening after the initial connection has been initiated, errors during transactions.
Bad Request Example:
email = 'foo'
customer_hash = FactoryBot.build(:customer, email: email)
begin
customers.create(customer_hash)
rescue OpenpayTransactionException => e
e.http_code # => 400
e.error_code # => 1001
e.description # => 'email\' not a well-formed email address'
end
Resource not found Example:
begin
#non existing customer
customers.delete('1111')
rescue OpenpayApiTransactionError => e
e.http_code # => 404
e.error_code # =>1005
e.description # =>"The customer with id '1111' does not exist"
end
For more information about categories, descriptions and codes take a look at:
In the Openpay dashboard you are able to see every request and its corresponding request/response.
For more use cases take a look at the test/spec folder
ruby client for Openpay api services (version 3.0.0)
This is a ruby client implementing the payment services for Openpay at openpay.pe
For more information about Openpay visit:
For the full Openpay api documentation take a look at:
Add the following line to your Gem file
#openpay gem
gem 'openpay'
Update your bundle:
$ bundle
Or install it from the command line:
$ gem install openpay
* ruby 2.4 or higher
require 'openpay'
#merchant and private key
merchant_id = 'mywvupjjs9xdnryxtplq'
private_key = 'sk_92b25d3baec149e6b428d81abfe37006'
country = 'pe'
#An openpay resource factory instance is created out of the OpenpayApi
#it points to the development environment by default.
#The country value can take 'mx' to Mexico or 'co' for Colombia or 'pe' for Peru
openpay = OpenpayApi.new(merchant_id, private_key, country,'pe')
#To enable production mode you should pass a third argument as true.
#openpay_prod=OpenpayApi.new(merchant_id,private_key,true)
#This ruby client manages a default timeout of 90 seconds to make the request
# to Openpay services, if you need to modify this value, you need to explicitly
# define the type of environment and followed by the new value for the timeout.
#Syntax:
# openpay_prod=OpenpayApi.new(merchant_id,private_key,isProduction,timeout)
#Example:
# openpay_prod=OpenpayApi.new(merchant_id,private_key,false,30)
The openpay factory instance is in charge to generate the required resources through a factory method (create). Resource classes should be initialized using the factory method as described below.
#creating an instance for each available resource
charges = openpay.create(:charges)
checkouts = openpay.create(:checkouts)
customers = openpay.create(:customers)
cards = openpay.create(:cards)
webhooks = openpay.create(:webhooks)
According to the current version of the Openpay api the available resources are:
Each rest resource exposed in the rest Openpay api is represented by a class in this ruby API, being ** OpenpayResource** the base class.
Each resource depending of its structure and available methods, will have one or more of the methods described under the methods subsection. Below a short description about the implementation high level details. For detailed documentation take a look a the openpay api documentation.
Given most resources belong, either to a merchant or a customer, the api was designed taking this in consideration, so:
The first argument represent the json/hash object, while the second argument which is optional represents the ** customer_id**. So if just one argument is provided the action will be performed at the merchant level, but if the second argument is provided passing the customer_id, the action will be performed at the customer level.
The following illustrates the api design.
#Merchant
hash_out = open_pay_resource.create(hash_in)
json_out = open_pay_resource.create(json_in)
#Customer
hash_out = open_pay_resource.create(hash_in, customer_id)
json_out = open_pay_resource.create(json_in, customer_id)
This api supports both ruby hashes and json strings as inputs and outputs. (See previous example) If a ruby hash is passed in as in input, a hash will be returned as the method output. if a json string is passed in as an input, a json string will be returned as the method function output.
This code excerpt from a specification demonstrates how you can use hashes and json strings interchangeably.
Methods without inputs will return a ruby hash.
it 'creates a fee using a json message' do
#create new customer
customer_hash = FactoryBot.build(:customer_col)
customer = @customers.create(customer_hash)
#create customer card , using factory girl to build the hash for us
card_hash = FactoryBot.build(:valid_card_col)
card = @cards.create(card_hash, customer['id'])
#create charge
charge_hash = FactoryBot.build(:card_charge_col, source_id: card['id'], order_id: card['id'], amount: 4000)
charge = @charges.create(charge_hash, customer['id'])
end
Here you can see how the card_hash representation looks like.
require 'pp'
pp card_hash =>
{ :holder_name => 'Vicente Olmos',
:card_number => '4111111111111111',
:cvv2 => '111',
:expiration_month => '09',
:expiration_year => '25' }
Next, how we construct the preceding hash using FactoryBot. FactoryBot was used in our test suite to facilitate hash construction. It may help you as well at your final implementation if you decide to use hashes. (more examples at test/Factories.rb)
FactoryBot.define do
factory :valid_card_col, class: Hash do
holder_name 'Vicente Olmos'
expiration_month '09'
card_number '4111111111111111'
expiration_year '14'
cvv2 '111'
initialize_with { attributes }
end
This ruby API standardize the method names across all different resources using the create,get,update and ** delete** verbs.
For full method documentation take a look at:
The test suite at test/spec is a good source of reference.
Creates the given resource
open_pay_resource.create(representation, customer_id = nil)
Gets an instance of a given resource
open_pay_resource.get(object_id, customer_id = nil)
Updates an instance of a given resource
open_pay_resource.update(representation, customer_id = nil)
Deletes an instance of the given resource
open_pay_resource.delete(object_id, customer_id = nil)
Returns an array of all instances of a resource
open_pay_resource.all(customer_id = nil)
Returns a block for each instance resource
open_pay_resource.each(customer_id = nil)
Deletes all instances of the given resource
#in case this method is executed under the production environment an OpenpayException will be raised.
open_pay_resource.delete_all(customer_id = nil)
creates merchant charge
charges.create(charge_hash)
creates customer charge
charges.create(charge_hash,customer_id)
gets merchant charge
merchant_charge=charges.get(charge_id)
gets customer charge
customer_charge=charges.get(charge_id,customer_id)
each merchant charge
charges.each {|charge| p charge}
list merchant / customer charges
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = charges.list(search_params)
customer_filtered_list = charges.list(search_params, customer_id)
each customer charge
charges.each(customer_id) {|charge| p charge}
all merchant charge
charges.all
all customer charge
charges.all(customer_id)
create checkout
checkouts.create(checkout_hash,customer_id)
checkouts.create(checkout_hash)
get chekout
checkouts.get(checkout_id)
creates a merchant card
cards.create(card_json)
creates a customer card
cards.create(card_hash, customer_id)
gets merchant card
card=cards.get(card_id)
gets customer card
card=cards.get(card_id, customer_id)
each merchant card
cards.each {|merchant_card| p card}
list merchant / customer cards
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
merchant_filtered_list = cards.list(search_params)
customer_filtered_list = cards.list(search_params, customer_id)
each customer card
cards.each(customer_id) {|customer_card | p customer_card }
all merchant cards
merchant_cards=cards.all
all customer cards
customer_cards=cards.all(customer_id)
delete merchant card
cards.delete(card_id)
delete customer card
cards.delete(card_id,customer_id)
delete all merchant cards
cards.delete_all
delete all customer cards
cards.delete_all(customer_id)
creates customer
customers.create(customer_json)
get customer
customer=customers.get(customer_id)
update customer
customers.update(customer_hash)
delete customer
customers.delete(customer_id)
each customer
customers.each do {|customer| p customer }
list customers
search_params = OpenpayUtils::SearchParams.new
search_params.limit = 1
customers_filtered_list = customers.list(search_params)
all customer
all_customers=customers.all
delete all customers (sand box mode only)
all_customers=customers.all
create webhook
webhooks.create(webhook_hash)
get webhook
webhook.get(webhook_id)
all webhooks
webhooks.all()
This API generates 3 different Exception classes.
OpenpayException: Generic base API exception class, Generic API exceptions.
Internal server error (500 Internal Server Error).
OpenpayApi factory method, invalid resource name.
Examples:
#production mode
openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
customers = openpay_prod.create(:customers)
customers.delete_all # will raise an OpenpayException
#production mode
openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
customers = openpay_prod.create(:non_existing_resource) # will raise an OpenpayException
OpenpayConnectionException: Exception class for connection related issues, errors happening prior the server connection.
Authentication Error (401 Unauthorized)
Connection Errors.
SSL Errors.
Example:
#invalid id and key
merchant_id = 'santa'
private_key = 'invalid'
openpay = OpenpayApi.new(merchant_id, private_key)
customers = openpay.create(:customers)
begin
customers.get('23444422211')
rescue OpenpayConnectionException => e
e.http_code # => 401
e.error_code # => 1002
e.description # => 'The api key or merchant id are invalid.'
e.json_body # {"category":"request","description":"The api key or merchant id are invalid.","http_code":401,"error_code":1002,"request_id":null}
end
OpenpayTransactionException: Errors happening after the initial connection has been initiated, errors during transactions.
Bad Request Example:
email = 'foo'
customer_hash = FactoryBot.build(:customer, email: email)
begin
customers.create(customer_hash)
rescue OpenpayTransactionException => e
e.http_code # => 400
e.error_code # => 1001
e.description # => 'email\' not a well-formed email address'
end
Resource not found Example:
begin
#non existing customer
customers.delete('1111')
rescue OpenpayApiTransactionError => e
e.http_code # => 404
e.error_code # =>1005
e.description # =>"The customer with id '1111' does not exist"
end
For more information about categories, descriptions and codes take a look at:
In the Openpay dashboard you are able to see every request and its corresponding request/response.
For more use cases take a look at the test/spec folder
FAQs
Unknown package
We found that openpay_copemx demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.