idx

package module
v0.0.0-...-f382fa0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2019 License: BSD-2-Clause Imports: 15 Imported by: 1

README

iDeal and iDIN

GoDoc

This is a Go library implementing the iDeal and iDIN protocols, as used by Dutch (and other) banks.

Current status

This library requires good XML signature support. Unfortunately, the best library I could find (github.com/russellhaering/goxmldsig) doesn't work well enough. Therefore, I patched it to get iDEAL to work. Unfortunately, iDIN support needs even more changes so is not supported at this time.

Usage

// Configure a client.
ideal := &idx.IDealClient{
    CommonClient: idx.CommonClient{
        BaseURL:    "", // provided by your bank
        MerchantID: "", // provided by your bank
        SubID:      "", // provided by your bank
        ReturnURL:  "", // the URL of your webapp that you will return to
        Certificate: tls.Certificate{ // keypair genered by you
            Certificate: [][]byte{cert}, // uploaded to the bank
            PrivateKey:  sk,
        },
        AcquirerCert: iDealAcquirerCert, // certificate provided by your bank
    },
}

// Create a transaction.
transaction := ideal.NewTransaction("<bankid>", "<purchaseID>", "1.00", "<description>", "<entranceCode>")
err := transaction.Start()
// handle error

// redirect the client to the bank
redirect(transaction.IssuerAuthenticationURL())

// after the client returns:
response, err := ideal.TransactionStatus(trxid)
// handle error
// do something with the response (check the iDEAL docs for requirements)

License

This library is licensed under the BSD 2-clause license. See LICENSE.txt for details.

Documentation

Overview

Package idx implements the iDeal and iDIN protocols, as used by Dutch banks.

The iDeal specification (merchant integration guide) can be viewed online from this URL: https://www.rabobank.nl/images/ideal_merchant_integration_guide_29696264.pdf

The iDIN specification is not available online, but can be requested with this form: https://www.idin.nl/identiteitdienstverleners/veelgestelde-vragen/documentatie-aanvragen/

Note that you should take a look at this documentation before using this library, as banks will often require you to follow certain practices! For example, every transaction *must* be closed, even if it is not successful (or if the consumer closes the web browser during the iDeal/iDIN transaction).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AcquirerError

type AcquirerError struct {
	ErrorCode       string // Short error code.
	ErrorMessage    string // Short human-readable error message.
	ErrorDetail     string // Longer human-readable error message, e.g. the origin of the error.
	ConsumerMessage string // The message to display on your website to the consumer.
}

AcquirerError may be returned by any API call to an iDeal/iDIN server.

func (AcquirerError) Error

func (e AcquirerError) Error() string

Error returns a string with the error code, error message and error detail string.

Note that when you hit this error, you should display the ConsumerMessage field of this struct to the user.

type Client

type Client interface {
	DirectoryRequest() (*Directory, error)
}

A Client implements common functionality between the iDeal and iDIN protocols.

type CommonClient

type CommonClient struct {
	BaseURL      string            // The API endpoint to use, as provided by your bank.
	MerchantID   string            // Merchant ID, as provided by your bank.
	SubID        string            // "0" if you don't use sub IDs.
	ReturnURL    string            // The URL to return to after the iDeal/iDIN transaction is complete.
	Certificate  tls.Certificate   // Your certificate, with which to sign outgoing messages.
	AcquirerCert *x509.Certificate // The certificate of the bank, with which to verify incoming messages.
}

The common client implements common functionality between iDeal and iDIN.

type Directory

type Directory struct {
	Issuers map[string][]Issuer `json:"issuers"`
}

The directory listing, as returned from a directory request. It is a map from country name to a list of issuers in that country.

type IDINAttribute

type IDINAttribute int
const (
	IDINServiceIDBIN         IDINAttribute = 1 << 14 // 16384
	IDINServiceIDName        IDINAttribute = 1 << 12 // 4096
	IDINServiceIDAddress     IDINAttribute = 1 << 10 // 1024
	IDINServiceIDDateOfBirth IDINAttribute = 7 << 6  // 64 | 128 | 256 = 448
	IDINServiceIDGender      IDINAttribute = 1 << 4  // 16
	IDINServiceIDTelephone   IDINAttribute = 1 << 2  // 4
	IDINServiceIDEmail       IDINAttribute = 1 << 1  // 2
)

Bits in the bitmask of requested attributes. Request multiple attribute kinds by ORing them toghether.

type IDINClient

type IDINClient struct {
	CommonClient
}

func (*IDINClient) DirectoryRequest

func (c *IDINClient) DirectoryRequest() (*Directory, error)

Do a directory request, to get a list of banks.

It should be issued at least once a week, but may not be issued very often (e.g. not every request). The recommended interval is once a week, see the iDIN specification for details ("iDIN Directory Protocol").

func (*IDINClient) NewTransaction

func (c *IDINClient) NewTransaction(issuer, entranceCode, id string, attributes IDINAttribute) *IDINTransaction

Create a transaction object but do not start it.

The issuer is the consumer-selected bank, the entranceCode is a session token to resume an existing session so the user doesn't get logged out during the iDIN transaction, and attributes is a set of flags indicating the requested attributes (request multiple attributes by ORing them together).

func (*IDINClient) TransactionStatus

func (c *IDINClient) TransactionStatus(trxid string) (*IDINTransactionStatus, error)

Request the status of a transaction. Returns an error on network/protocol/signature errors. Note that when it does not return an error, the status may still be something other than "Success", you will have to handle each possible status.

This call may only be done once upon redirection from the consumer bank. See 11.5 "Restrictions on AcquirerStatusReq" in the iDIN specification for details.

type IDINTransaction

type IDINTransaction struct {
	// contains filtered or unexported fields
}

func (*IDINTransaction) IssuerAuthenticationURL

func (t *IDINTransaction) IssuerAuthenticationURL() string

Return the URL to which to redirect the consumer to start the iDIN process for the consumer.

func (*IDINTransaction) Start

func (t *IDINTransaction) Start() error

Start a transaction.

Note that you must save the transaction ID upon creation, so that it can be closed after a day or so when the client closes the browser window/tab before completion.

func (*IDINTransaction) TransactionID

func (t *IDINTransaction) TransactionID() string

Return the transaction ID, useful for logging.

type IDINTransactionStatus

type IDINTransactionStatus struct {
	Status     TransactionStatus
	Attributes map[string]string
}

IDINTransactionStatus is the result of doing a status request of an iDIN transaction. The returned attributes are only present after a successful transaction.

type IDealClient

type IDealClient struct {
	CommonClient
}

func (*IDealClient) DirectoryRequest

func (c *IDealClient) DirectoryRequest() (*Directory, error)

Do a directory request, to get a list of banks.

It should be executed somewhere between once a day and once a month, and specifically must not be executed on each request. This means you have to cache the returned list of banks.

func (*IDealClient) NewTransaction

func (c *IDealClient) NewTransaction(issuer, purchaseID, amount, description, entranceCode string) *IDealTransaction

Create a transaction object but do not start it.

The issuer is the bank ID selected by the consumer, purchaseID is an unique number for this transaction in your system and will appear in the consumer's bank notes, description is the text to show in the client's bank notes, and entranceCode is a session token you can use to resume the (possibly expired) session when the consumer returns to your website.

func (*IDealClient) TransactionStatus

func (c *IDealClient) TransactionStatus(trxid string) (*IDealTransactionStatus, error)

Request the status of a transaction. Returns an error on network/protocol errors. Note that you must check the Status field manually.

There are limits on how often you can call this function, see the specification for details ("Collection duty").

type IDealTransaction

type IDealTransaction struct {
	// contains filtered or unexported fields
}

A single iDeal transaction.

func (*IDealTransaction) IssuerAuthenticationURL

func (t *IDealTransaction) IssuerAuthenticationURL() string

Return the URL to redirect the user to to start authentication.

func (*IDealTransaction) Start

func (t *IDealTransaction) Start() error

Start a transaction.

Note that you must save the transaction ID upon creation, so that it can be closed after a day or so when the client closes the browser window/tab before completion. Also, you are required to deliver something when the transaction was completed (even when the consumer doesn't return to your website after completion), see the documentation for details.

func (*IDealTransaction) TransactionID

func (t *IDealTransaction) TransactionID() string

Return the transaction ID, useful for logging.

type IDealTransactionStatus

type IDealTransactionStatus struct {
	Status       TransactionStatus
	ConsumerName string // ConsumerName: the full name of one or even multiple consumers.
	ConsumerIBAN string
	ConsumerBIC  string
	Amount       string // for example, "1.00"
	Currency     string // for example, "EUR"
}

The returned transaction status after a status request. Fields besides Status are only set when Status equals Success.

type Issuer

type Issuer struct {
	IssuerID   string `json:"issuerID"`   // BIC
	IssuerName string `json:"issuerName"` // Human-readable name
}

A single issuer (bank), as returned in a directory request.

type TransactionStatus

type TransactionStatus int
const (
	InvalidStatus TransactionStatus = iota
	Success
	Cancelled
	Expired
	Failure
	Open
)

TransactionStatus is an enum of the possible statuses of an iDeal/iDIN transaction.

func (TransactionStatus) String

func (status TransactionStatus) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL