Git Product home page Git Product logo

ruby-sdk's Introduction

wallee Ruby Library

The wallee Ruby library wraps around the wallee API. This library facilitates your interaction with various services such as transactions, accounts, and subscriptions.

Documentation

wallee Web Service API

Requirements

  • Ruby 3.0.0+

Installation

RubyGem install (recommended)

$ gem install wallee-ruby-sdk

Usage

The library needs to be configured with your account's space id, user id, and secret key which are available in your wallee account dashboard. Set space_id, user_id, and api_secret to their values. You can also optionally set default_headers to set some headers that will be sent to all requests:

Configuring a Service

require 'wallee-ruby-sdk'

space_id = 405
app_user_id = 512
app_user_key = "FKrO76r5VwJtBrqZawBspljbBNOxp5veKQQkOnZxucQ="

# default_headers is an optional param, that represents headers sent to all requests
# timeout is an optional param, that allows to configure custom timeout (default is 25 seconds)
Wallee.configure do |config|
  config.user_id = app_user_id
  config.authentication_key = app_user_key
  config.default_headers = {"x-meta-custom-header": 'value-1', "x-meta-custom-header-2": 'value-2'}
  config.timeout = 60
end

# TransactionService
transaction_service = Wallee::TransactionService.new
# TransactionPaymentPageService
transaction_payment_page_service = Wallee::TransactionPaymentPageService.new

To get stated with sending transactions you can review the example below:

require 'wallee-ruby-sdk'

space_id = 405
app_user_id = 512
app_user_key = "FKrO76r5VwJtBrqZawBspljbBNOxp5veKQQkOnZxucQ="

# timeout is an optional param, that allows to configure custom timeout (default is 25 seconds)
Wallee.configure do |config|
    config.user_id = app_user_id
    config.authentication_key = app_user_key
    config.timeout = 60
end

# TransactionService
transaction_service = Wallee::TransactionService.new
# TransactionPaymentPageService
transaction_payment_page_service = Wallee::TransactionPaymentPageService.new

transaction = Wallee::TransactionCreate.new({
    billingAddress: Wallee::AddressCreate.new({
        city: "City",
        country: "US",
        emailAddress: "[email protected]",
        familyName: "Family",
        givenName: "Given",
        postCode: "98100",
        postalState: "WA",
        street: "Street"
    }),
    currency: 'EUR',
    customerEmailAddress: "[email protected]",
    customerPresence: Wallee::CustomersPresence::VIRTUAL_PRESENT,
    failedUrl: "http://localhost/failure",
    invoiceMerchantReference: "order-1",
    language: "en_US",
    lineItems: [
        Wallee::LineItemCreate.new({
            amountIncludingTax: 29.60,
            name: "Item 1",
            quantity: 1,
            shippingRequired: true,
            sku: "sku-1",
            taxes: [
                Wallee::TaxCreate.new({
                    rate: 8,
                    title: "VAT"
                })
            ],
            type: Wallee::LineItemType::PRODUCT,
            uniqueId: "unique-id-item-1",
        }),
        Wallee::LineItemCreate.new({
            amountIncludingTax: 5.60,
            name: "Test Shipping",
            quantity: 1,
            shippingRequired: false,
            sku: "test-shipping",
            taxes: [
                Wallee::TaxCreate.new({
                    rate: 8,
                    title: "VAT"
                })
            ],
            type: Wallee::LineItemType::SHIPPING,
            uniqueId: "unique-id-shipping-1",
        }),
    ],
    merchantReference: "order-1",
    shippingAddress: Wallee::AddressCreate.new({
        city: "City",
        country: "US",
        emailAddress: "[email protected]",
        familyName: "Family",
        givenName: "Given",
        postCode: "98100",
        postalState: "WA",
        street: "Street"
    }),
    shippingMethod: "Test Shipping",
    successUrl: "http://localhost/success"
})

transaction = transaction_service.create(space_id, transaction)
payment_page_url = transaction_payment_page_service.payment_page_url(space_id, transaction.id)
# redirect to payment_page_url

Integrating Webhook Payload Signing Mechanism into webhook callback handler

The HTTP request which is sent for a state change of an entity now includes an additional field state, which provides information about the update of the monitored entity's state. This enhancement is a result of the implementation of our webhook encryption mechanism.

Payload field state provides direct information about the state update of the entity, making additional API calls to retrieve the entity state redundant.

⚠️ Warning: Generic Pseudocode

The provided pseudocode is intentionally generic and serves to illustrate the process of enhancing your API to leverage webhook payload signing. It is not a complete implementation.

Please ensure that you adapt and extend this code to meet the specific needs of your application, including appropriate security measures and error handling. For a detailed webhook payload signing mechanism understanding we highly recommend referring to our comprehensive Webhook Payload Signing Documentation.

post '/webhook/callback' do
    request_payload = request.body.read
    signature = request.env['HTTP_X_SIGNATURE']

    if signature.nil? || signature.empty?
        # Make additional API call to retrieve the entity state
        # ...
    else
        if webhook_encryption_service.is_content_valid(signature, request_payload)
            # Parse request_payload to extract 'state' value
            # Process entity's state change
            # ...
        end
    end

    # Process the received webhook data
    # ...
end

License

Please see the license file for more information.

ruby-sdk's People

Contributors

andrewrowanwallee avatar edgaraswallee avatar nicoeigenmanncw avatar pulkit110 avatar rubenjohn-wallee avatar rytisre avatar schmijos avatar schurter-wallee avatar simon-isler avatar vttn avatar wallee-deployment-user avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ruby-sdk's Issues

Threaded Rails on macOS

I stumbled over this error on my macOS Sonoma 14.3 with the typheous gem (using libcurl) when calling the wallee API with the SDK:

objc[43182]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
objc[43182]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
 We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

The solution for my local setup was to set OBJC_DISABLE_INITIALIZE_FORK_SAFETY.
I got the hint from here: https://stackoverflow.com/a/59315607/430418

Handle missing configuration gracefully

I come from a configuration like this:

if Rails.env.production? && ENV["SKIP_WALLEE"].blank?
  Wallee.configure do |config|
    config.user_id = ENV["WALLEE_APP_USER_ID"]
    config.authentication_key = ENV["WALLEE_APP_AUTHENTICATION_KEY"]
  end
end

I wanted to write tests and they failed because requests to the Wallee API without configuring authentication will fail in base64.rb (str.unpack1("m")):

     NoMethodError:
       undefined method `unpack1' for nil:NilClass

This was difficult to relate to the cause.
It would be nice if you could check for a valid config in Wallee::ApiClient#initialize and raise a readable message like "Missing app user credentials!"

401 - Unauthorized when request doesn't contain query params

Whenever a request does not contain query params, the API client encodes the incorrect URL with an extra ? (for example: http://app-wallee.com/api/account/create?) in x-mac-key which results in 401 errors. I have tried a fix locally and it works when changing

completed_path = "#{base_url.path}#{path}"+'?'+query.map{|k,v| "#{k}=#{v}"}.join('&')
to

completed_path = "#{base_url.path}#{path}"
completed_path += "?" + query.map{|k,v| "#{k}=#{v}"}.join('&') unless query.empty?

Here are the failed request logs if you need them:

D, [2021-01-12T12:14:41.171627 #90679] DEBUG -- : Calling API: ApplicationUserService.create ...
D, [2021-01-12T12:14:41.172147 #90679] DEBUG -- : HTTP request body param ~BEGIN~
{"name":"API User","state":"ACTIVE","primaryAccount":{"id":REDACTED}}
~END~

Found bundle for host app-wallee.com: 0x7fbe1887ea00 [can multiplex]
Re-using existing connection! (#0) with host app-wallee.com
Connected to app-wallee.com (104.20.89.191) port 443 (#0)
Using Stream ID: 3 (easy handle 0x7fbe1821e400)
POST /api/application-user/create HTTP/2
Host: app-wallee.com
User-Agent: Typhoeus
Content-Type: application/json;charset=utf-8
Accept: application/json;charset=utf-8
x-mac-version: 1
x-mac-userid: ...
x-mac-timestamp: 1610450081
x-mac-value: ...
Content-Length: 66

We are completely uploaded and fine
HTTP/2 401 
date: Tue, 12 Jan 2021 11:14:41 GMT
content-type: text/html;charset=utf-8
set-cookie: ...
strict-transport-security: max-age=15552000; includeSubDomains; preload
cf-cache-status: DYNAMIC
cf-request-id: 0797e72e570000103fdea07000000001
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
set-cookie: language=en-US; Path=/; Secure; HttpOnly
x-content-type-options: nosniff
x-svid: 0f55a8df3c435e082
x-url: https://app-wallee.com:443/api/application-user/create

Connection #0 to host app-wallee.com left intact
D, [2021-01-12T12:14:41.451859 #90679] DEBUG -- : HTTP response body ~BEGIN~
<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8"/>
                <meta http-equiv="Content-type" content="text/html; charset=utf-8">
                <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
                <title>Error</title>
                <link rel="icon" type="image/png" href="/assets/images/favicon.png" />
                                        <link type="text/css" rel="stylesheet" media="all" href="/error-page-assets/bootstrap.css" />
                        <link type="text/css" rel="stylesheet" media="all" href="/error-page-assets/layout.css" />
                                <script>
                // We need to force a reload when the back button is used in the browser.
                window.addEventListener( "popstate", function ( event ) { window.location.reload(true); });
                </script>
        </head>
        <body class="error">
                <div class="container">
                                <div class="container-error">
                <div class="col-sm-6 col-xs-12">
                        <h1>Ooops!</h1>
                        <h2>Sorry, something went wrong!</h2>
                        <span>Error code: 401</span>
                        <span>Please contact us and we will try to solve this issue.</span>
                </div>
                <div class="col-sm-6 hidden-xs">
                        <img src="/assets/images/error/internal-exception.svg" class="img-responsive" />
                </div>
        </div>
                </div>
        </body>
</html>
~END~

Simple Example: Unauthorized

I'm not able to test the example in your Readme. I've copy and pasted it. Also I configured in the app rules that is has account admin privileges.

require 'sinatra'
require 'wallee-ruby-sdk'

# Setup userId and authenticationKey
Wallee.configure do |config|
  config.debugging = true
  config.user_id = '841'
  config.authentication_key = '******'
end

api_instance = Wallee::AccountService.new

opts = {
    filter: Wallee::EntityQueryFilter.new # EntityQueryFilter | The filter which restricts the entities which are used to calculate the count.
}

begin
  #Count
  result = api_instance.account_service_count(opts)
  p result
rescue Wallee::ApiError => e
  puts "Exception when calling AccountService->account_service_count: #{e}"
end

This is the output:

/Users/josua/.rbenv/shims/bundle exec ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/josua/projects/wallee/app.rb
D, [2017-09-26T12:31:56.718672 #77762] DEBUG -- : Calling API: AccountService.account_service_count ...
D, [2017-09-26T12:31:56.718910 #77762] DEBUG -- : HTTP request body param ~BEGIN~
{}
~END~

  Trying 104.20.251.70...
Connected to app-wallee.com (104.20.251.70) port 443 (#0)
TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Server certificate: *.app-wallee.com
Server certificate: COMODO RSA Domain Validation Secure Server CA
Server certificate: COMODO RSA Certification Authority
Server certificate: AddTrust External CA Root
POST /api/account/count HTTP/1.1
Host: app-wallee.com
User-Agent: Typhoeus
Content-Type: application/json;charset=utf-8
Accept: application/json;charset=utf-8
x-mac-version: 1
x-mac-userid: 841
x-mac-timestamp: 1506421916
x-mac-value: ******
Content-Length: 2

upload completely sent off: 2 out of 2 bytes
HTTP/1.1 401 Unauthorized
Date: Tue, 26 Sep 2017 10:31:58 GMT
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=******; expires=Wed, 26-Sep-18 10:31:57 GMT; path=/; domain=.app-wallee.com; HttpOnly
X-SVID: *******
Set-Cookie: _csrf_token_443=******;Path=/;Expires=Tue, 26-Sep-2017 11:31:58 GMT;Max-Age=3600;Secure;HttpOnly
Set-Cookie: language=en-US;Path=/;Secure;HttpOnly
X-URL: https://app-wallee.com:443/api/account/count
Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Server: cloudflare-nginx
CF-RAY: 3a458e79b90d3e56-ZRH

Connection #0 to host app-wallee.com left intact
D, [2017-09-26T12:31:57.235680 #77762] DEBUG -- : HTTP response body ~BEGIN~
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8"/>
		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
		<title>Error</title>
		<link rel="icon" type="image/png" href="/assets/images/favicon.png" />
 					<link type="text/css" rel="stylesheet" media="all" href="/error-page-assets/bootstrap.css" />
			<link type="text/css" rel="stylesheet" media="all" href="/error-page-assets/layout.css" />
			</head>
	<body class="error">
		<div class="container">
			<div class="layout-header">
				<div class="navbar-header">
					<a class="navbar-brand" href="/"><img src="/assets/images/wallee-logo-primary.svg" /></a>
				</div>
			</div>
				<div class="container-error">
		<div class="col-sm-6 col-xs-12">
			<h1>Ooops!</h1>
			<h2>Sorry, something went wrong!</h2>
			<span>Error code: 401</span>
			<span>Please contact us and we will try to solve this issue.</span>
		</div>
		<div class="col-sm-6 hidden-xs">
			<img src="/assets/images/error/internal-exception.svg" class="img-responsive" />
		</div>
	</div>
		</div>
	</body>
</html>
~END~

Exception when calling AccountService->account_service_count: Unauthorized
[2017-09-26 12:31:57] INFO  WEBrick 1.3.1
[2017-09-26 12:31:57] INFO  ruby 2.4.2 (2017-09-14) [x86_64-darwin15]
== Sinatra (v1.4.8) has taken the stage on 4567 for development with backup from WEBrick
[2017-09-26 12:31:57] INFO  WEBrick::HTTPServer#start: pid=77762 port=4567

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.