An open API service indexing awesome lists of open source software.

https://github.com/simplificator/datatrans

A simple implementation of the Datatrans API (see datatrans.ch)
https://github.com/simplificator/datatrans

Last synced: 10 months ago
JSON representation

A simple implementation of the Datatrans API (see datatrans.ch)

Awesome Lists containing this project

README

          

Datatrans
=========

Ruby adapter for the Datatrans payment gateway (http://www.datatrans.ch).

Configuration
-------------

Build your Datatrans Configuration like so:

```ruby
datatrans = Datatrans::Config.new(
:merchant_id => '1234567',
:sign_key => 'ab739fd5b7c2a1...',
:password => 'server to server request password',
:environment => :production,
:proxy => {
:http_proxyaddr => "proxy.com",
:http_proxyport => 80,
:http_proxyuser => "hans",
:http_proxpass => "xxx",
}
)
```

If you don't want to use signed requests (disabled in datatrans web console), you can set `config.sign_key` to `false`.
The configuration is then used as parameter to all the constructors and helpers, see examples below.

Possible values for the environment: `:production`, `:development`

Web Authorization
=================

> [!IMPORTANT]
>
> Datatrans no longer supports the Payment Page API. The support in this gem will be removed in the next major release. Please use the [JSON API](#json-transactions) instead.

If you want to process a credit card the first time a web authorization is
necessary. Add the following code to a controller action that shows the form.
You need to pass at least `amount`, `currency` and `refno` (order number).
```ruby
@transaction = datatrans.web_transaction(
:amount => 1000, # in cents!
:currency => 'CHF',
:refno => 'ABCDEF',
:uppCustomerEmail => 'customer@email.com',
# feel free to add more upp infos here ...
)
```

In your View your show the credit card form with a convenient helper:

```ruby
= form_tag Datatrans.web_authorize_url do

= text_field_tag :paymentmethod, 'ECA'
= text_field_tag :cardno
= text_field_tag :expm
= text_field_tag :expy
= text_field_tag :cvv

= hidden_field_tag :successUrl,
= hidden_field_tag :cancelUrl,
= hidden_field_tag :errorUrl,

= datatrans_notification_request_hidden_fields(datatrans, @transaction)

= submit_tag "send"
```

In this example we use just ECA (Mastercard) as paymentmethod. Feel free to
provide an appropriate select field to offer more payment methods. Don't forget
to add `successUrl`, `cancelUrl` and `errorUrl`. We recommend to set them all
to the same value.

After you submit the request to Datatrans they redirect back to your application.
Now you can process the transaction like this:
```ruby
begin
transaction = datatrans.web_transaction(params)

if transaction.authorize
# transaction was successful, access the following attributes
# transaction.transaction_id
# transaction.creditcard_alias
# transaction.masked_cc
# transaction.authorization_code
# ...

else
# transaction was not successful, accces the error details
# transaction.error_code, transaction.error_message, transaction.error_detail

end
rescue Datatrans::InvalidSignatureError => exception
# the signature was wrong, the request may have been compromised...
end
```

JSON Transactions
=================

More information about Datatrans JSON API can be found [here](https://api-reference.datatrans.ch/). Our gem uses endpoints from `/v1/transactions` section.

We implemented support for [Redirect mode](https://docs.datatrans.ch/docs/redirect-lightbox) (since Lightbox mode may not work correctly on mobile, whereas Redirect works well on all devices).

Saving Payment Information
--------------------------

According to the [docs](https://docs.datatrans.ch/docs/customer-initiated-payments#saving-payment-information), there are three possible flows:

- **Customer Initiated Payments**: _Your customer pays and nothing is registered._
- This is the most basic setup and does _not_ save any payment information: First, call `transaction.init`, and then redirect the user to the `transaction_path` (see the sections `Initialize` and `Start a transaction` below).
- **Customer Initiated Payment** and creating an `alias` for subsequent **Merchant Initiated Payments**: _Your customer pays and the card or payment method information is registered. You receive an alias which you save for later merchant initiated payments or one-click checkouts._
- In order to save payment information after your customer has finalized their payment, without them having to re-enter their payment information and go through the 3D-Secure flow, pass `option: {"createAlias": true}`. More information can be found [here](https://docs.datatrans.ch/docs/redirect-lightbox#saving-payment-information).
- **Merchant Initiated Payments**: _Your customer registers their card or payment method information without any payment. Their account is not charged. This is what we call a dedicated registration._
- This setup allows you to save a customers payment information without any charge in the beginning. This is useful in the context of setting up a subscription model (e.g., usage-based billing at the end of a billing period). See the section `Merchant Initiated Payments` below.

Initialize
---------

Initialize a JSON transaction:

```ruby
transaction = datatrans.json_transaction(
refno: 'ABCDEF',
amount: 1000, # in cents!
currency: "CHF",
payment_methods: ["ECA", "VIS"],
success_url: ,
cancel_url: ,
error_url:
)

# call to initialize endpoint to initialize a transaction
# returns true or false depending if response was successful or not
init = transaction.init

# successful authorization call returns in response a transaction id
if init
transaction_id = transaction.response.params["transactionId"]
end
```

Start a transaction
-------------------

Once you have a transaction id, you can start a transaction. Users of your application will be redirected to the datatrans payment pages: `https://pay.sandbox.datatrans.com/v1/start/{{transactionId}}`.

```ruby
path = datatrans.json_transaction(transaction_id: transaction_id).transaction_path

redirect_to path
# or if you redirect after AJAX request:
render js: "window.location='#{path}'"
```

You do not have to [settle a transaction](https://api-reference.datatrans.ch/#tag/v1transactions/operation/settle) by yourself: we set `"autoSettle": true` by default when authorizing a transaction, which means the transaction will be settled automatically. This can be overridden by setting `auto_settle: false` when authorizing a transaction.

Transaction status
------------------

You can check the trasaction [status](https://api-reference.datatrans.ch/#tag/v1transactions/operation/status), see its history and retrieve the card information.

```ruby
transaction = datatrans.json_transaction(transaction_id: transaction_id)

# status method returns true or false depending if response was successfull
if transaction.status
data = transaction.response.params
# this will return following hash (may vary dependong on your payment method):
{
"transactionId"=>"230223022302230223",
"merchantId"=>"1100000000",
"type"=>"payment",
"status"=>"settled",
"currency"=>"CHF",
"refno"=>"123456abc",
"paymentMethod"=>"VIS",
"detail"=>
{"authorize"=>{"amount"=>1000, "acquirerAuthorizationCode"=>"100000"}, "settle"=>{"amount"=>1000}},
"language"=>"en",
"card"=>
{"masked"=>"400000xxxxxx0018",
"expiryMonth"=>"06",
"expiryYear"=>"25",
"info"=>
{"brand"=>"VISA",
"type"=>"debit",
"usage"=>"consumer",
"country"=>"SE",
"issuer"=>"SVENSKA HANDELSBANKEN AB"},
"3D"=>{"authenticationResponse"=>"Y"}},
"history"=>
[{"action"=>"init",
"amount"=>1000,
"source"=>"api",
"date"=>"2023-06-06T08:37:23Z",
"success"=>true,
"ip"=>"8.8.8.8"},
{"action"=>"authorize",
"autoSettle"=>true,
"amount"=>1000,
"source"=>"redirect",
"date"=>"2023-06-06T08:37:42Z",
"success"=>true,
"ip"=>"8.8.8.8"}]
}
else
transaction.response.error_code
transaction.response.error_message
end
```

Merchant Initiated Payments
---------

It's possible to authorize transactions without user interaction, via [merchant initiated payments](https://docs.datatrans.ch/docs/merchant-initiated-payments).

To perform a so-called "dedicated registration" (so we can later charge the card via its `alias`), you should follow the same steps as described above, but not provide an amount:

```ruby
transaction = datatrans.json_transaction(
refno: 'ABCDEF',
amount: 0, # omit amount for dedicated registrations
currency: "CHF",
payment_methods: ["ECA", "VIS"],
success_url: ,
cancel_url: ,
error_url:
)

init = transaction.init

# successful authorization call returns in response a transaction id
if init
transaction_id = transaction.response.params["transactionId"]
end
```

Then, at a later point in time, and without needing any user interaction, you can create a payment via `merchant_authorize`:

```ruby
dedicated_registration = datatrans.json_transaction(transaction_id: transaction_id)
dedicated_registration.status # this will contain the card information

card_alias = dedicated_registration.response.params["card"]["alias"]
card_expiry_month = dedicated_registration.response.params["card"]["expiryMonth"]
card_expiry_year = dedicated_registration.response.params["card"]["expiryYear"]

transaction = datatrans.json_transaction(
refno: "ABCDEF",
amount: 1000,
currency: "CHF",
card: {alias: card_alias, expiryMonth: card_expiry_month, expiryYear: card_expiry_year}
)

transaction.merchant_authorize # this will charge the card without user interaction
```

XML Transactions
================

> [!IMPORTANT]
>
> Datatrans will stop supporting the XML API on June 3rd, 2024. The support in this gem will be removed in the next major release. Please use the [JSON API](#json-transactions) instead.

If you have already a credit card alias or an authorized transaction you can
use the convenient XML methods to process payments.

Authorize
---------

```ruby
transaction = datatrans.xml_transaction(
:refno => 'ABCDEF',
:amount => 1000, # in cents!
:currency => 'CHF',
:aliasCC => '8383843729284848348',
:expm => 12,
:expy => 15,
)

if transaction.authorize
# ok, the transaction is authorized...
# access same values as in the web authorization (e.g. transaction.transaction_id)
else
# transaction.error_code, transaction.error_message, transaction.error_detail
end
```

Capture
-------

To capture an authorized transaction you use the following code:

```ruby
transaction = datatrans.xml_transaction(
:refno => 'ABCDEF',
:amount => 1000, # in cents!
:currency => 'CHF',
:transaction_id => 19834324987349723948729834,
)

if transaction.capture
# ok, the money is yours...
else
# transaction.error_code, transaction.error_message, transaction.error_detail
end
```

Void
----

To make an authorized transaction invalid use void.

```ruby
transaction = datatrans.xml_transaction(
:refno => 'ABCDEF',
:amount => 1000, # in cents!
:currency => 'CHF',
:transaction_id => 19834324987349723948729834,
)

if transaction.void
# ok, the transaction is not longer valid...
else
# transaction.error_code, transaction.error_message, transaction.error_detail
end
```

Todo
====

* allow signing of xml transactions
* allow signing with different keys
* add credit method to reverse already captured transactions
* add purchase method to authorize and capture in one step
* add url helpers for success, cancel and error urls
* extend configuration possibilities
* dry code more

Contribute
==========

* Fork the project.
* Make your feature addition or bug fix.
* Add specs for it. This is important so we don't break it in a
future version unintentionally.
* Commit, do not mess with rakefile, version, or history.
(if you want to have your own version, that is fine but bump version in a commit by itself we can ignore when we pull)
* Send us a pull request. Bonus points for topic branches.

Credits
=======

Datatrans is maintained by Simplificator GmbH (http://simplificator.com).

The initial development was sponsered by Evita AG and Limmex AG.

License
=======

Datatrans is released under the MIT license.