diff --git a/CHANGELOG.md b/CHANGELOG.md index 00bb4a5..1e6ae19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ Given a version number MAJOR.MINOR.PATCH, increment: ## [Unreleased] +### Added +- merchantSession, merchantPurchase, merchantCard, merchantInstallment ## [2.13.0] - 2025-03-17 ### Added diff --git a/README.md b/README.md index 25e9c91..ad4e391 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,10 @@ is as easy as sending a text message to your client! - [CorporateBalance](#get-your-corporatebalance): View your corporate balance - [CorporateTransactions](#query-corporatetransactions): View the transactions that have affected your corporate balance - [CorporateEnums](#corporate-enums): Query enums related to the corporate purchases, such as merchant categories, countries and card purchase methods + - [MerchantSession](#merchant-session): The Merchant Session allows you to create a session prior to a purchase. Sessions are essential for defining the parameters of a purchase, including funding type, expiration, 3DS, and more. + - [MerchantCard](#merchant-card): The Merchant Card resource stores information about cards used in approved purchases. + - [MerchantInstallment](#merchant-installment): Merchant Installments are created for every installment in a purchase. + - [MerchantPurchase](#merchant-purchase): The Merchant Purchase section allows users to retrieve detailed information of the purchases. - [Webhooks](#create-a-webhook-subscription): Configure your webhook endpoints and subscriptions - [WebhookEvents](#process-webhook-events): Manage webhook events - [WebhookEventAttempts](#query-failed-webhook-event-delivery-attempts-information): Query failed webhook event deliveries @@ -2221,6 +2225,157 @@ methods.each do |method| end ``` +## Merchant Session + +The Merchant Session allows you to create a session prior to a purchase. +Sessions are essential for defining the parameters of a purchase, including funding type, expiration, 3DS, and more. + +## Create a MerchantSession + +```ruby +require('starkbank') + +session = { + allowed_funding_types: ['debit', 'credit'], + allowed_installments: [ + { total_amount: 0, count: 1 }, + { total_amount: 120, count: 2 }, + { total_amount: 180, count: 12 } + ], + expiration: 3600, + challenge_mode: challenge_mode, + tags: ['yourTags'] +} + +merchant_session = StarkBank::MerchantSession.create(session) + +puts merchant_session +``` + +You can create a MerchantPurchase through a MerchantSession by passing its UUID. +**Note**: This method must be implemented in your front-end to ensure that sensitive card data does not pass through the back-end of the integration. + +### Create a MerchantSession Purchase + +```ruby +require('starkbank') + +session_purchase = { + amount: 180, + installment_count: 12, + card_expiration: '2035-01', + card_number: '5277696455399733', + card_security_code: '123', + holder_name: 'Holder Name', + holder_email: 'holdeName@email.com', + holder_phone: '11111111111', + funding_type: 'credit', + billing_country_code: 'BRA', + billing_city: 'São Paulo', + billing_state_code: 'SP', + billing_street_line_1: 'Rua do Holder Name, 123', + billing_street_line_2: '', + billing_zip_code: '11111-111', + metadata: { + user_agent: 'Postman', + user_ip: '255.255.255.255', + language: 'pt-BR', + timezone_offset: 3, + extra_data: 'extraData' + } +} + +purchase = StarkBank::MerchantSession.purchase( + uuid: "c32f9d2385974957a777f8351921afd7", + payload: session_purchase +) + +puts purchase +``` + +### Query MerchantSessions +```ruby +require('starkbank') + +merchant_sessions = StarkBank::MerchantSession.query(limit: 3).to_a +merchant_sessions.each do |merchant_session| + puts merchant_session +end +``` + +### Get a MerchantSession +```ruby +require('starkbank') + +merchant_session = StarkBank::MerchantSession.get("5130086357401600") +puts merchant_session +``` +## Merchant Purchase +The Merchant Purchase section allows users to retrieve detailed information of the purchases. + +### Query MerchantPurchases +```ruby +require('starkbank') + +merchant_purchases = StarkBank::MerchantPurchase.query(limit: 3).to_a +merchant_purchases.each do |session| + puts session +end +``` +### Get a MerchantPurchase +```ruby +require('starkbank') + +merchant_purchase = StarkBank::MerchantPurchase.get("5130086357401600") +puts merchant_purchase +``` + +## Merchant Card + +The Merchant Card resource stores information about cards used in approved purchases. +These cards can be used in new purchases without the need to create a new session. + +### Query MerchantCards +```ruby +require('starkbank') + +merchant_cards = StarkBank::MerchantCard.query(limit: 3).to_a +merchant_cards.each do |card| + puts card +end +``` + +### Get a MerchantCard +```ruby +require('starkbank') + +merchant_card = StarkBank::MerchantCard.get("5130086357401600") +puts merchant_card +``` + +## Merchant Installment + +Merchant Installments are created for every installment in a purchase. +These resources will track its own due payment date and settlement lifecycle. + +### Query MerchantInstallments +```ruby +require('starkbank') + +merchant_installments = StarkBank::MerchantInstallment.query(limit: 3).to_a +merchant_installments.each do |installment| + puts installment +end +``` + +### Get a MerchantInstallment +```ruby +require('starkbank') + +merchant_installment = StarkBank::MerchantCard.get("5130086357401600") +puts merchant_installment +``` + ## Create a webhook subscription To create a webhook subscription and be notified whenever an event occurs, run: diff --git a/lib/merchant_card/log.rb b/lib/merchant_card/log.rb new file mode 100644 index 0000000..56f7f26 --- /dev/null +++ b/lib/merchant_card/log.rb @@ -0,0 +1,68 @@ +require('starkcore') +require_relative('../utils/rest') +require_relative('merchant_card') + + +module StarkBank + class MerchantCard + class Log < StarkCore::Utils::Resource + attr_reader :id, :created, :type, :errors, :card + def initialize(id:, created:, type:, errors:, card:) + super(id) + @created = StarkCore::Utils::Checks.check_datetime(created) + @type = type + @errors = errors + @card = card + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, after: nil, before: nil, types: nil, card_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + types: types, + card_ids: card_ids, + user: user, + **resource + ) + end + + def self.page(cursor: nil, limit: nil, after: nil, before: nil, types: nil, card_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + return StarkBank::Utils::Rest.get_page( + cursor: cursor, + limit: limit, + after: after, + before: before, + types: types, + card_ids: card_ids, + user: user, + **resource + ) + end + + def self.resource + card_maker = StarkBank::MerchantCard.resource[:resource_maker] + { + resource_name: 'MerchantCardLog', + resource_maker: proc { |json| + Log.new( + id: json['id'], + created: json['created'], + type: json['type'], + errors: json['errors'], + card: StarkCore::Utils::API.from_api_json(card_maker, json['card']) + ) + } + } + end + end + end +end diff --git a/lib/merchant_card/merchant_card.rb b/lib/merchant_card/merchant_card.rb new file mode 100644 index 0000000..c880ba6 --- /dev/null +++ b/lib/merchant_card/merchant_card.rb @@ -0,0 +1,71 @@ +require 'starkcore' +require_relative '../utils/rest' + + +module StarkBank + class MerchantCard < StarkCore::Utils::Resource + attr_reader :created, :ending, :expiration, :fundingType, :holderName, :id, :network, :status, :tags, :updated + + def initialize(ending:, expiration:, fundingType:, holderName:, id: nil, created: nil, network: nil, status: nil, tags: nil, updated: nil) + super(id) + @ending = ending + @expiration = expiration + @fundingType = fundingType + @holderName = holderName + @created = StarkCore::Utils::Checks.check_datetime(created) + @network = network + @status = status + @tags = tags + @updated = StarkCore::Utils::Checks.check_datetime(updated) + end + + def self.resource + { + resource_name: 'MerchantCard', + resource_maker: proc { |json| + MerchantCard.new( + ending: json['ending'], + expiration: json['expiration'], + fundingType: json['fundingType'], + holderName: json['holderName'], + id: json['id'], + created: json['created'], + network: json['network'], + status: json['status'], + tags: json['tags'], + updated: json['updated'] + ) + } + } + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, status: nil, tags: nil, ids: nil, after: nil, before: nil, user: nil) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + + def self.page(limit: nil, cursor: nil, status: nil, tags: nil, ids: nil, user: nil) + StarkBank::Utils::Rest.get_page( + limit: limit, + cursor: cursor, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + end +end diff --git a/lib/merchant_installment/log.rb b/lib/merchant_installment/log.rb new file mode 100644 index 0000000..b41ea98 --- /dev/null +++ b/lib/merchant_installment/log.rb @@ -0,0 +1,68 @@ +require('starkcore') +require_relative('../utils/rest') +require_relative('merchant_installment') + + +module StarkBank + class MerchantInstallment + class Log < StarkCore::Utils::Resource + attr_reader :id, :created, :type, :errors, :installment + def initialize(id:, created:, type:, errors:, installment:) + super(id) + @created = StarkCore::Utils::Checks.check_datetime(created) + @type = type + @errors = errors + @installment = installment + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, after: nil, before: nil, types: nil, installment_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + types: types, + installment_ids: installment_ids, + user: user, + **resource + ) + end + + def self.page(cursor: nil, limit: nil, after: nil, before: nil, types: nil, installment_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + return StarkBank::Utils::Rest.get_page( + cursor: cursor, + limit: limit, + after: after, + before: before, + types: types, + installment_ids: installment_ids, + user: user, + **resource + ) + end + + def self.resource + installment_maker = StarkBank::MerchantInstallment.resource[:resource_maker] + { + resource_name: 'MerchantInstallmentLog', + resource_maker: proc { |json| + Log.new( + id: json['id'], + created: json['created'], + type: json['type'], + errors: json['errors'], + installment: StarkCore::Utils::API.from_api_json(installment_maker, json['installment']) + ) + } + } + end + end + end +end diff --git a/lib/merchant_installment/merchant_installment.rb b/lib/merchant_installment/merchant_installment.rb new file mode 100644 index 0000000..efd78b5 --- /dev/null +++ b/lib/merchant_installment/merchant_installment.rb @@ -0,0 +1,77 @@ +require 'starkcore' +require_relative '../utils/rest' + + +module StarkBank + class MerchantInstallment < StarkCore::Utils::Resource + attr_reader :amount, :created, :due, :fee, :fundingType, :id, :network, :purchaseId, :status, :tags, :transactionIds, :updated + + def initialize(amount:, fundingType:, purchaseId:, due:, id: nil, created: nil, fee: nil, network: nil, status: nil, tags: nil, transactionIds: nil, updated: nil) + super(id) + @amount = amount + @fundingType = fundingType + @purchaseId = purchaseId + @due = due + @created = StarkCore::Utils::Checks.check_datetime(created) + @fee = fee + @network = network + @status = status + @tags = tags + @transactionIds = transactionIds + @updated = StarkCore::Utils::Checks.check_datetime(updated) + end + + def self.resource + { + resource_name: 'MerchantInstallment', + resource_maker: proc { |json| + MerchantInstallment.new( + amount: json['amount'], + fundingType: json['fundingType'], + purchaseId: json['purchaseId'], + due: json['due'], + id: json['id'], + created: json['created'], + fee: json['fee'], + network: json['network'], + status: json['status'], + tags: json['tags'], + transactionIds: json['transactionIds'], + updated: json['updated'] + ) + } + } + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, status: nil, tags: nil, ids: nil, after: nil, before: nil, user: nil) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + + def self.page(cursor: nil, limit: nil, status: nil, tags: nil, ids: nil, after: nil, before: nil, user: nil) + StarkBank::Utils::Rest.get_page( + cursor: cursor, + limit: limit, + after: after, + before: before, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + end +end diff --git a/lib/merchant_purchase/log.rb b/lib/merchant_purchase/log.rb new file mode 100644 index 0000000..9607f10 --- /dev/null +++ b/lib/merchant_purchase/log.rb @@ -0,0 +1,68 @@ +require('starkcore') +require_relative('../utils/rest') +require_relative('merchant_purchase') + + +module StarkBank + class MerchantPurchase + class Log < StarkCore::Utils::Resource + attr_reader :id, :created, :type, :errors, :purchase + def initialize(id:, created:, type:, errors:, purchase:) + super(id) + @created = StarkCore::Utils::Checks.check_datetime(created) + @type = type + @errors = errors + @purchase = purchase + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, after: nil, before: nil, types: nil, purchase_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + types: types, + purchase_ids: purchase_ids, + user: user, + **resource + ) + end + + def self.page(cursor: nil, limit: nil, after: nil, before: nil, types: nil, purchase_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + return StarkBank::Utils::Rest.get_page( + cursor: cursor, + limit: limit, + after: after, + before: before, + types: types, + purchase_ids: purchase_ids, + user: user, + **resource + ) + end + + def self.resource + purchase_maker = StarkBank::MerchantPurchase.resource[:resource_maker] + { + resource_name: 'MerchantPurchaseLog', + resource_maker: proc { |json| + Log.new( + id: json['id'], + created: json['created'], + type: json['type'], + errors: json['errors'], + purchase: StarkCore::Utils::API.from_api_json(purchase_maker, json['purchase']) + ) + } + } + end + end + end +end diff --git a/lib/merchant_purchase/merchant_purchase.rb b/lib/merchant_purchase/merchant_purchase.rb new file mode 100644 index 0000000..fb75b0f --- /dev/null +++ b/lib/merchant_purchase/merchant_purchase.rb @@ -0,0 +1,117 @@ +require 'starkcore' +require_relative '../utils/rest' + + +module StarkBank + class MerchantPurchase < StarkCore::Utils::Resource + attr_reader :amount, :billing_city, :billing_country_code, :billing_state_code, :billing_street_line1, :billing_street_line2, :billing_zip_code, :card_ending, :card_id, :challenge_mode, :challenge_url, :created, :currency_code, :end_to_end_id, :fee, :funding_type, :holder_email, :holder_name, :holder_phone, :id, :installment_count, :metadata, :network, :source, :status, :tags, :updated + + def initialize( + amount:, funding_type:, card_id:, billing_city: nil, billing_country_code: nil, billing_state_code: nil, billing_street_line1: nil, billing_street_line2: nil, billing_zip_code: nil, card_ending: nil, challenge_mode: nil, challenge_url: nil, created: nil, currency_code: nil, end_to_end_id: nil, fee: nil, holder_email: nil, holder_name: nil, holder_phone: nil, id: nil, installment_count: nil, metadata: nil, network: nil, source: nil, status: nil, tags: nil, updated: nil + ) + super(id) + @amount = amount + @billing_city = billing_city + @billing_country_code = billing_country_code + @billing_state_code = billing_state_code + @billing_street_line1 = billing_street_line1 + @billing_street_line2 = billing_street_line2 + @billing_zip_code = billing_zip_code + @card_ending = card_ending + @card_id = card_id + @challenge_mode = challenge_mode + @challenge_url = challenge_url + @created = StarkCore::Utils::Checks.check_datetime(created) + @currency_code = currency_code + @end_to_end_id = end_to_end_id + @fee = fee + @funding_type = funding_type + @holder_email = holder_email + @holder_name = holder_name + @holder_phone = holder_phone + @installment_count = installment_count + @metadata = metadata + @network = network + @source = source + @status = status + @tags = tags + @updated = StarkCore::Utils::Checks.check_datetime(updated) + end + + def self.resource + { + resource_name: 'MerchantPurchase', + resource_maker: proc { |json| + MerchantPurchase.new( + id: json['id'], + amount: json['amount'], + billing_city: json['billingCity'], + billing_country_code: json['billingCountryCode'], + billing_state_code: json['billingStateCode'], + billing_street_line1: json['billingStreetLine1'], + billing_street_line2: json['billingStreetLine2'], + billing_zip_code: json['billingZipCode'], + card_ending: json['cardEnding'], + card_id: json['cardId'], + challenge_mode: json['challengeMode'], + challenge_url: json['challengeUrl'], + created: json['created'], + currency_code: json['currencyCode'], + end_to_end_id: json['endToEndId'], + fee: json['fee'], + funding_type: json['fundingType'], + holder_email: json['holderEmail'], + holder_name: json['holderName'], + holder_phone: json['holderPhone'], + installment_count: json['installmentCount'], + metadata: json['metadata'], + network: json['network'], + source: json['source'], + status: json['status'], + tags: json['tags'], + updated: json['updated'] + ) + } + } + end + + def self.create(purchase, user: nil) + StarkBank::Utils::Rest.post_single(entity: purchase, resource_name: 'MerchantPurchase', user: user, **resource) + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, status: nil, tags: nil, ids: nil, after: nil, before: nil, user: nil) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + + def self.page(cursor: nil, limit: nil, status: nil, tags: nil, ids: nil, after: nil, before: nil, user: nil) + StarkBank::Utils::Rest.get_page( + cursor: cursor, + limit: limit, + after: after, + before: before, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + + def self.update(id, payload, user: nil) + StarkBank::Utils::Rest.patch_id(id: id, user: user, **resource, **payload) + end + end +end diff --git a/lib/merchant_session/allowed_installments.rb b/lib/merchant_session/allowed_installments.rb new file mode 100644 index 0000000..c596248 --- /dev/null +++ b/lib/merchant_session/allowed_installments.rb @@ -0,0 +1,26 @@ +require 'starkcore' + + +module StarkBank + class AllowedInstallment < StarkCore::Utils::SubResource + attr_reader :total_amount, :count + + def initialize(total_amount:, count:) + super() + @total_amount = total_amount + @count = count + end + + def self.resource + { + resource_name: 'AllowedInstallment', + resource_maker: proc { |json| + AllowedInstallment.new( + total_amount: json['total_amount'], + count: json['count'] + ) + } + } + end + end +end diff --git a/lib/merchant_session/log.rb b/lib/merchant_session/log.rb new file mode 100644 index 0000000..dac0cca --- /dev/null +++ b/lib/merchant_session/log.rb @@ -0,0 +1,70 @@ +require('starkcore') +require_relative('../utils/rest') +require_relative('merchant_session') + + +module StarkBank + class MerchantSession + + class Log < StarkCore::Utils::Resource + attr_reader :id, :created, :type, :errors, :session + def initialize(id:, created:, type:, errors:, session:) + super(id) + @created = StarkCore::Utils::Checks.check_datetime(created) + @type = type + @errors = errors + @session = session + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, after: nil, before: nil, types: nil, session_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + types: types, + session_ids: session_ids, + user: user, + **resource + ) + end + + def self.page(cursor: nil, limit: nil, after: nil, before: nil, types: nil, session_ids: nil, user: nil) + after = StarkCore::Utils::Checks.check_date(after) + before = StarkCore::Utils::Checks.check_date(before) + return StarkBank::Utils::Rest.get_page( + cursor: cursor, + limit: limit, + after: after, + before: before, + types: types, + session_ids: session_ids, + user: user, + **resource + ) + end + + def self.resource + session_maker = StarkBank::MerchantSession.resource[:resource_maker] + { + resource_name: 'MerchantSessionLog', + resource_maker: proc { |json| + Log.new( + id: json['id'], + created: json['created'], + type: json['type'], + errors: json['errors'], + session: StarkCore::Utils::API.from_api_json(session_maker, json['session']) + ) + } + } + end + end + end +end + diff --git a/lib/merchant_session/merchant_session.rb b/lib/merchant_session/merchant_session.rb new file mode 100644 index 0000000..6f67359 --- /dev/null +++ b/lib/merchant_session/merchant_session.rb @@ -0,0 +1,99 @@ +require 'starkcore' +require_relative '../utils/rest' +require_relative 'allowed_installments' + + +module StarkBank + class MerchantSession < StarkCore::Utils::Resource + attr_reader :allowed_funding_types, :allowed_installments, :expiration, :allowed_ips, :challenge_mode, :status, :tags, :created, :updated, :uuid + + def initialize( + allowed_funding_types:, allowed_installments:, expiration:, id: nil, allowed_ips: nil, challenge_mode: nil, created: nil, status: nil, tags: nil, updated: nil, uuid: nil + ) + super(id) + @allowed_funding_types = allowed_funding_types + @allowed_installments = parse_allowed_installments(allowed_installments) + @allowed_ips = allowed_ips + @challenge_mode = challenge_mode + @expiration = expiration + @status = status + @tags = tags + @created = StarkCore::Utils::Checks.check_datetime(created) + @updated = StarkCore::Utils::Checks.check_datetime(updated) + @uuid = uuid + end + + def self.resource + { + resource_name: 'MerchantSession', + resource_maker: proc { |json| + MerchantSession.new( + id: json['id'], + allowed_funding_types: json['allowed_funding_types'], + allowed_installments: json['allowed_installments'].map { |installment| StarkBank::AllowedInstallment.resource[:resource_maker].call(installment) }, + allowed_ips: json['allowed_ips'], + challenge_mode: json['challenge_mode'], + expiration: json['expiration'], + status: json['status'], + tags: json['tags'], + created: json['created'], + updated: json['updated'], + uuid: json['uuid'] + ) + } + } + end + + def self.create(merchant_session, user: nil) + StarkBank::Utils::Rest.post_single(entity: merchant_session, user: user, **resource) + end + + def self.get(id, user: nil) + StarkBank::Utils::Rest.get_id(id: id, user: user, **resource) + end + + def self.query(limit: nil, status: nil, tags: nil, ids: nil, after: nil, before: nil, user: nil) + StarkBank::Utils::Rest.get_stream( + limit: limit, + after: after, + before: before, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + + def self.page(cursor: nil, limit: nil, status: nil, tags: nil, ids: nil, after: nil, before: nil, user: nil) + StarkBank::Utils::Rest.get_page( + cursor: cursor, + limit: limit, + after: after, + before: before, + status: status, + tags: tags, + ids: ids, + user: user, + **resource + ) + end + + def self.purchase(uuid:, payload:, user: nil) + StarkBank::Utils::Rest.post_sub_resource(id: uuid, entity: payload, user: user, **resource, **StarkBank::MerchantSession::Purchase.resource) + end + + private + + def parse_allowed_installments(allowed_installments) + return nil if allowed_installments.nil? + allowed_installments.map do |allowed_installment| + if allowed_installment.is_a?(StarkBank::AllowedInstallment) + allowed_installment + else + StarkCore::Utils::API.from_api_json(StarkBank::AllowedInstallment.resource, allowed_installment) + end + end + end + end +end diff --git a/lib/merchant_session/purchase.rb b/lib/merchant_session/purchase.rb new file mode 100644 index 0000000..1204549 --- /dev/null +++ b/lib/merchant_session/purchase.rb @@ -0,0 +1,88 @@ +require 'starkcore' +require_relative '../utils/rest' +require_relative 'merchant_session' + + +module StarkBank + class MerchantSession + class Purchase < StarkCore::Utils::Resource + attr_reader :amount, :card_expiration, :card_number, :card_security_code, :holder_name, :funding_type, :holder_email, :holder_phone, :installment_count, :billing_country_code, :billing_city, :billing_state_code, :billing_street_line_1, :billing_street_line_2, :billing_zip_code, :metadata, :card_ending, :card_id, :challenge_mode, :challenge_url, :created, :currency_code, :end_to_end_id, :fee, :network, :source, :status, :tags, :updated + + def initialize( + amount:, card_expiration:, card_number:, card_security_code:, holder_name:, funding_type:, id: nil, holder_email: nil, holder_phone: nil, installment_count: nil, billing_country_code: nil, billing_city: nil, billing_state_code: nil, billing_street_line_1: nil, billing_street_line_2: nil, billing_zip_code: nil, metadata: nil, card_ending: nil, card_id: nil, challenge_mode: nil, challenge_url: nil, created: nil, currency_code: nil, end_to_end_id: nil, fee: nil, network: nil, source: nil, status: nil, tags: nil, updated: nil + ) + super(id) + @amount = amount + @card_expiration = card_expiration + @card_number = card_number + @card_security_code = card_security_code + @holder_name = holder_name + @funding_type = funding_type + @holder_email = holder_email + @holder_phone = holder_phone + @installment_count = installment_count + @billing_country_code = billing_country_code + @billing_city = billing_city + @billing_state_code = billing_state_code + @billing_street_line_1 = billing_street_line_1 + @billing_street_line_2 = billing_street_line_2 + @billing_zip_code = billing_zip_code + @metadata = metadata + @card_ending = card_ending + @card_id = card_id + @challenge_mode = challenge_mode + @challenge_url = challenge_url + @created = StarkCore::Utils::Checks.check_datetime(created) + @currency_code = currency_code + @end_to_end_id = end_to_end_id + @fee = fee + @network = network + @source = source + @status = status + @tags = tags + @updated = StarkCore::Utils::Checks.check_datetime(updated) + end + + def self.resource + { + sub_resource_name: 'Purchase', + sub_resource_maker: proc { |json| + Purchase.new( + id: json['id'], + amount: json['amount'], + card_expiration: json['card_expiration'], + card_number: json['card_number'], + card_security_code: json['card_security_code'], + holder_name: json['holder_name'], + funding_type: json['funding_type'], + holder_email: json['holder_email'], + holder_phone: json['holder_phone'], + installment_count: json['installment_count'], + billing_country_code: json['billing_country_code'], + billing_city: json['billing_city'], + billing_state_code: json['billing_state_code'], + billing_street_line_1: json['billing_street_line_1'], + billing_street_line_2: json['billing_street_line_2'], + billing_zip_code: json['billing_zip_code'], + metadata: json['metadata'], + card_ending: json['card_ending'], + card_id: json['card_id'], + challenge_mode: json['challenge_mode'], + challenge_url: json['challenge_url'], + created: json['created'], + currency_code: json['currency_code'], + end_to_end_id: json['end_to_end_id'], + fee: json['fee'], + network: json['network'], + source: json['source'], + status: json['status'], + tags: json['tags'], + updated: json['updated'] + ) + } + } + end + end + end +end + diff --git a/lib/starkbank.rb b/lib/starkbank.rb index 5547aa9..e207965 100644 --- a/lib/starkbank.rb +++ b/lib/starkbank.rb @@ -56,6 +56,16 @@ require_relative('payment_preview/utility_preview') require_relative('institution/institution') require_relative('request/request') +require_relative('merchant_session/merchant_session') +require_relative('merchant_session/log') +require_relative('merchant_session/purchase') +require_relative('merchant_session/allowed_installments') +require_relative('merchant_purchase/merchant_purchase') +require_relative('merchant_purchase/log') +require_relative('merchant_installment/merchant_installment') +require_relative('merchant_installment/log') +require_relative('merchant_card/merchant_card') +require_relative('merchant_card/log') # SDK to facilitate Ruby integrations with Stark Bank module StarkBank diff --git a/lib/utils/rest.rb b/lib/utils/rest.rb index 6a8d0ad..9cae838 100755 --- a/lib/utils/rest.rb +++ b/lib/utils/rest.rb @@ -97,6 +97,22 @@ def self.get_sub_resources(resource_name:, sub_resource_maker:, sub_resource_nam ) end + def self.post_sub_resource(resource_name:, sub_resource_maker:, sub_resource_name:, entity:, user:, id:, **query) + return StarkCore::Utils::Rest.post_sub_resource( + resource_name: resource_name, + sub_resource_maker: sub_resource_maker, + sub_resource_name: sub_resource_name, + sdk_version: StarkBank::SDK_VERSION, + host: StarkBank::HOST, + api_version: StarkBank::API_VERSION, + user: user ? user : StarkBank.user, + language: StarkBank.language, + timeout: StarkBank.timeout, + entity: entity, + id: id, + ) + end + def self.post(resource_name:, resource_maker:, user:, entities:, **query) return StarkCore::Utils::Rest.post( resource_name: resource_name, diff --git a/starkbank.gemspec b/starkbank.gemspec index e2b4a78..beb2962 100644 --- a/starkbank.gemspec +++ b/starkbank.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.files = Dir['lib/**/*.rb'] s.license = 'MIT' s.required_ruby_version = '>= 2.3' - s.add_dependency('starkcore', '~> 0.2.2') + s.add_dependency('starkcore', '~> 0.3.0') s.add_development_dependency('minitest', '~> 5.14.1') s.add_development_dependency('rake', '~> 13.0') s.add_development_dependency('rubocop', '~> 0.81') diff --git a/test/example_generator.rb b/test/example_generator.rb index e8bc35a..ec1c2b0 100644 --- a/test/example_generator.rb +++ b/test/example_generator.rb @@ -271,4 +271,67 @@ def self.organization_example private_key: ENV['SANDBOX_ORGANIZATION_PRIVATE_KEY'] # '-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBEcEJZLk/DyuXVsEjz0w4vrE7plPXhQxODvcG1Jc0WToAcGBSuBBAAK\noUQDQgAE6t4OGx1XYktOzH/7HV6FBukxq0Xs2As6oeN6re1Ttso2fwrh5BJXDq75\nmSYHeclthCRgU8zl6H1lFQ4BKZ5RCQ==\n-----END EC PRIVATE KEY-----' ) end + + def self.generate_example_merchant_session_json(challenge_mode) + { + allowed_funding_types: ['debit', 'credit'], + allowed_installments: [ + { total_amount: 0, count: 1 }, + { total_amount: 120, count: 2 }, + { total_amount: 180, count: 12 } + ], + expiration: 3600, + challenge_mode: challenge_mode, + tags: ['yourTags'] + } + end + + def self.generate_example_merchant_session_purchase_challenge_mode_disabled_json + { + amount: 180, + installment_count: 12, + card_expiration: '2035-01', + card_number: '5277696455399733', + card_security_code: '123', + holder_name: 'Holder Name', + funding_type: 'credit' + } + end + + def self.generate_example_merchant_session_purchase_challenge_mode_enabled_json + { + amount: 180, + installment_count: 12, + card_expiration: '2035-01', + card_number: '5277696455399733', + card_security_code: '123', + holder_name: 'Holder Name', + holder_email: 'holdeName@email.com', + holder_phone: '11111111111', + funding_type: 'credit', + billing_country_code: 'BRA', + billing_city: 'São Paulo', + billing_state_code: 'SP', + billing_street_line_1: 'Rua do Holder Name, 123', + billing_street_line_2: '', + billing_zip_code: '11111-111', + metadata: { + user_agent: 'Postman', + user_ip: '255.255.255.255', + language: 'pt-BR', + timezone_offset: 3, + extra_data: 'extraData' + } + } + end + + def self.merchant_purchase_example + StarkBank::MerchantPurchase.new( + amount: 1000, + funding_type: 'credit', + card_id: '5113758527520768', + challenge_mode: 'disabled' + ) + end end + diff --git a/test/starkbank/test_merchant_card.rb b/test/starkbank/test_merchant_card.rb new file mode 100644 index 0000000..9561f74 --- /dev/null +++ b/test/starkbank/test_merchant_card.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') +require_relative('../example_generator.rb') + +describe(StarkBank::MerchantCard, '#merchant_card#') do + it 'query' do + merchant_cards = StarkBank::MerchantCard.query(limit: 3).to_a + merchant_cards.each do |installment| + merchant_card = StarkBank::MerchantCard.get(installment.id) + expect(merchant_card.id).wont_be_nil + end + end + + it 'get' do + merchant_cards = StarkBank::MerchantCard.query(limit: 3).to_a + merchant_cards.each do |installment| + merchant_card = StarkBank::MerchantCard.get(installment.id) + expect(merchant_card.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + (0..1).step(1) do + page, cursor = StarkBank::MerchantCard.page(limit: 5, cursor: cursor) + page.each do |entity| + expect(ids).wont_include(entity.id) + ids << entity.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end +end diff --git a/test/starkbank/test_merchant_card_log.rb b/test/starkbank/test_merchant_card_log.rb new file mode 100644 index 0000000..2765d44 --- /dev/null +++ b/test/starkbank/test_merchant_card_log.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') + +describe(StarkBank::MerchantCard::Log, '#merchant_card/log#') do + it 'query logs' do + logs = StarkBank::MerchantCard::Log.query(limit: 10).to_a + expect(logs.length).must_equal(10) + logs.each do |log| + expect(log.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + logs = nil + (0..1).step(1) do + logs, cursor = StarkBank::MerchantCard::Log.page(limit: 5, cursor: cursor) + logs.each do |log| + expect(ids).wont_include(log.id) + ids << log.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end + + it 'query and get' do + log = StarkBank::MerchantCard::Log.query(limit: 1).to_a[0] + get_log = StarkBank::MerchantCard::Log.get(log.id) + expect(log.id).must_equal(get_log.id) + end +end diff --git a/test/starkbank/test_merchant_installment.rb b/test/starkbank/test_merchant_installment.rb new file mode 100644 index 0000000..01bff2f --- /dev/null +++ b/test/starkbank/test_merchant_installment.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') +require_relative('../example_generator.rb') + +describe(StarkBank::MerchantInstallment, '#merchant_installment#') do + it 'query' do + merchant_installments = StarkBank::MerchantInstallment.query(limit: 3).to_a + merchant_installments.each do |installment| + merchant_installment = StarkBank::MerchantInstallment.get(installment.id) + expect(merchant_installment.id).wont_be_nil + end + end + + it 'get' do + merchant_installments = StarkBank::MerchantInstallment.query(limit: 3).to_a + merchant_installments.each do |installment| + merchant_installment = StarkBank::MerchantInstallment.get(installment.id) + expect(merchant_installment.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + (0..1).step(1) do + page, cursor = StarkBank::MerchantInstallment.page(limit: 5, cursor: cursor) + page.each do |entity| + expect(ids).wont_include(entity.id) + ids << entity.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end +end diff --git a/test/starkbank/test_merchant_installment_log.rb b/test/starkbank/test_merchant_installment_log.rb new file mode 100644 index 0000000..92b52ad --- /dev/null +++ b/test/starkbank/test_merchant_installment_log.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') + +describe(StarkBank::MerchantInstallment::Log, '#merchant_installment/log#') do + it 'query logs' do + logs = StarkBank::MerchantInstallment::Log.query(limit: 10).to_a + expect(logs.length).must_equal(10) + logs.each do |log| + expect(log.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + logs = nil + (0..1).step(1) do + logs, cursor = StarkBank::MerchantInstallment::Log.page(limit: 5, cursor: cursor) + logs.each do |log| + expect(ids).wont_include(log.id) + ids << log.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end + + it 'query and get' do + log = StarkBank::MerchantInstallment::Log.query(limit: 1).to_a[0] + get_log = StarkBank::MerchantInstallment::Log.get(log.id) + expect(log.id).must_equal(get_log.id) + end +end diff --git a/test/starkbank/test_merchant_purchase.rb b/test/starkbank/test_merchant_purchase.rb new file mode 100644 index 0000000..f5515e0 --- /dev/null +++ b/test/starkbank/test_merchant_purchase.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') +require_relative('../example_generator.rb') + +describe(StarkBank::MerchantPurchase, '#merchant_purchase#') do + + it 'create' do + merchant_purchase_example = ExampleGenerator.merchant_purchase_example + merchant_purchase = StarkBank::MerchantPurchase.create(merchant_purchase_example) + expect(merchant_purchase.id).wont_be_nil + end + + it 'query' do + merchant_purchases = StarkBank::MerchantPurchase.query(limit: 3).to_a + merchant_purchases.each do |session| + merchant_purchase = StarkBank::MerchantPurchase.get(session.id) + expect(merchant_purchase.id).wont_be_nil + end + end + + it 'get' do + merchant_purchases = StarkBank::MerchantPurchase.query(limit: 3).to_a + merchant_purchases.each do |session| + merchant_purchase = StarkBank::MerchantPurchase.get(session.id) + expect(merchant_purchase.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + (0..1).step(1) do + page, cursor = StarkBank::MerchantPurchase.page(limit: 5, cursor: cursor) + page.each do |entity| + expect(ids).wont_include(entity.id) + ids << entity.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end + + it 'update' do + merchant_purchases = StarkBank::MerchantPurchase.query(status: "paid").to_a + merchant_purchase_id = merchant_purchases[0].id + merchant_purchase = StarkBank::MerchantPurchase.update(merchant_purchase_id, { "amount": 0, "status": "reversed" }) + expect(merchant_purchase.id).must_equal(merchant_purchase_id) + end +end diff --git a/test/starkbank/test_merchant_purchase_log.rb b/test/starkbank/test_merchant_purchase_log.rb new file mode 100644 index 0000000..40ee284 --- /dev/null +++ b/test/starkbank/test_merchant_purchase_log.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') + +describe(StarkBank::MerchantPurchase::Log, '#merchant_purchase/log#') do + it 'query logs' do + logs = StarkBank::MerchantPurchase::Log.query(limit: 10).to_a + expect(logs.length).must_equal(10) + logs.each do |log| + expect(log.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + logs = nil + (0..1).step(1) do + logs, cursor = StarkBank::MerchantPurchase::Log.page(limit: 5, cursor: cursor) + logs.each do |log| + expect(ids).wont_include(log.id) + ids << log.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end + + it 'query and get' do + log = StarkBank::MerchantPurchase::Log.query(limit: 1).to_a[0] + get_log = StarkBank::MerchantPurchase::Log.get(log.id) + expect(log.id).must_equal(get_log.id) + end +end diff --git a/test/starkbank/test_merchant_session.rb b/test/starkbank/test_merchant_session.rb new file mode 100644 index 0000000..8599133 --- /dev/null +++ b/test/starkbank/test_merchant_session.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') +require_relative('../example_generator.rb') + +describe(StarkBank::MerchantSession, '#merchant_session#') do + it 'create' do + merchant_session_json = ExampleGenerator.generate_example_merchant_session_json("disabled") + merchant_session = StarkBank::MerchantSession.create(merchant_session_json) + expect(merchant_session.id).wont_be_nil + end + + it 'query' do + merchant_sessions = StarkBank::MerchantSession.query(limit: 3).to_a + merchant_sessions.each do |merchant_session| + expect(merchant_session.id).wont_be_nil + end + end + + it 'get' do + merchant_sessions = StarkBank::MerchantSession.query(limit: 3).to_a + merchant_sessions.each do |session| + merchant_session = StarkBank::MerchantSession.get(session.id) + expect(merchant_session.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + (0..1).step(1) do + page, cursor = StarkBank::MerchantSession.page(limit: 5, cursor: cursor) + page.each do |entity| + expect(ids).wont_include(entity.id) + ids << entity.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end + + it 'purchase challenge mode disabled' do + merchant_session = StarkBank::MerchantSession.create(ExampleGenerator.generate_example_merchant_session_json("disabled")) + merchant_session_purchase_json = ExampleGenerator.generate_example_merchant_session_purchase_challenge_mode_disabled_json() + merchant_session_purchase = StarkBank::MerchantSession.purchase( + uuid: merchant_session.uuid, + payload: merchant_session_purchase_json + ) + expect(merchant_session_purchase.id).wont_be_nil + end + + it 'purchase challenge mode enabled' do + merchant_session_json = ExampleGenerator.generate_example_merchant_session_json("enabled") + merchant_session = StarkBank::MerchantSession.create(merchant_session_json) + merchant_session_purchase_json = ExampleGenerator.generate_example_merchant_session_purchase_challenge_mode_enabled_json() + purchase = StarkBank::MerchantSession.purchase( + uuid: merchant_session.uuid, + payload: merchant_session_purchase_json + ) + expect(purchase.id).wont_be_nil + end +end diff --git a/test/starkbank/test_merchant_session_log.rb b/test/starkbank/test_merchant_session_log.rb new file mode 100644 index 0000000..e60a542 --- /dev/null +++ b/test/starkbank/test_merchant_session_log.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative('../test_helper.rb') + +describe(StarkBank::MerchantSession::Log, '#merchant_session/log#') do + it 'query logs' do + logs = StarkBank::MerchantSession::Log.query(limit: 10).to_a + expect(logs.length).must_equal(10) + logs.each do |log| + expect(log.id).wont_be_nil + end + end + + it 'page' do + ids = [] + cursor = nil + logs = nil + (0..1).step(1) do + logs, cursor = StarkBank::MerchantSession::Log.page(limit: 5, cursor: cursor) + logs.each do |log| + expect(ids).wont_include(log.id) + ids << log.id + end + break if cursor.nil? + end + expect(ids.length).must_equal(10) + end + + it 'query and get' do + log = StarkBank::MerchantSession::Log.query(limit: 1).to_a[0] + get_log = StarkBank::MerchantSession::Log.get(log.id) + expect(log.id).must_equal(get_log.id) + end +end