README
¶
Sleet
Payment abstraction library - interact with different Payment Service Providers (PsP) with one unified interface.
Installation
go get github.com/BoltApp/sleet
Methodology
Wherever possible, we try to use native Golang implementations of the PsP's API. We also assume that the caller can pass along raw credit card information (i.e. are PCI compliant)
Supported Gateway API Calls
- Authorize
- Capture
- Void
- Refund
Webhooks Support
We support abstracting PsP Webhook notifications into a common interface.
PsP Support Matrix
PsP | Gateway APIs | Webhooks |
---|---|---|
Adyen | ✅ | ❌ |
Authorize.Net | ✅ | ❌ |
Braintree | ✅ | ❌ |
CyberSource | ✅ | ❌ |
Checkout.com | ✅ | ❌ |
FirstData | ✅ | ❌ |
NMI | ✅ | ❌ |
Orbital | ✅ | ❌ |
RocketGate | ✅ | ❌ |
Stripe | ✅ | ❌ |
To run tests
Unit test
go test -v -tags=unit $(go list ./... | grep -v integration-tests)
Integration test
The following environment variables are needed in order to run tests
$ export ADYEN_USERNAME="YOUR_ADYEN_WEBSERVICE_USERNAME"
$ export ADYEN_ACCOUNT="YOUR_ADYEN_MERCHANT_ACCOUNT"
$ export ADYEN_PASSWORD="YOUR_ADYEN_WEBSERVICE_PASSWORD"
$ export STRIPE_TEST_KEY="YOUR_STRIPE_API_KEY"
$ export AUTH_NET_LOGIN_ID="YOUR_AUTHNET_LOGIN"
$ export AUTH_NET_TXN_KEY="YOUR_AUTHNET_TXN_KEY"
$ export BRAINTREE_MERCHANT_ID="YOUR_BRAINTREE_MERCHANT_ACCOUNT"
$ export BRAINTREE_PUBLIC_KEY="YOUR_BRAINTREE_PUBLIC_KEY"
$ export BRAINTREE_PRIVATE_ID="YOUR_BRAINTREE_PRIVATE_KEY"
$ export CYBERSOURCE_ACCOUNT="YOUR_CYBS_ACCOUNT"
$ export CYBERSOURCE_API_KEY="YOUR_CYBS_KEY"
$ export CYBERSOURCE_SHARED_SECRET="YOUR_CYBS_SECRET"
$ export NMI_SECURITY_KEY="YOUR_NMI_PRIVATE_KEY"
$ export CHECKOUTCOM_TEST_KEY="YOUR_CHECKOUTCOM_PRIVATE_KEY"
$ export CHECKOUTCOM_TEST_KEY_WITH_PCID="YOUR_CHECKOUTCOM_PRIVATE_KEY_WITH_PROCESSING_CHANNEL_ID"
$ export CHECKOUTCOM_TEST_PCID="YOUR_CHECKOUTCOM_PROCESSING_CHANNEL_ID"
Then run tests with: go test ./integration-tests/
Code Example for Auth + Capture
import (
"github.com/BoltApp/sleet"
"github.com/BoltApp/sleet/gateways/authorize_net"
)
// Generate a client using your own credentials
client := authorize_net.NewClient("AUTH_NET_LOGIN_ID", "AUTH_NET_TXN_KEY")
amount := sleet.Amount{
Amount: 100,
Currency: "USD",
}
card := sleet.CreditCard{
FirstName: "Bolt",
LastName: "Checkout",
Number: "4111111111111111",
ExpMonth: 8,
EpxYear: 2010,
CVV: "000",
}
streetAddress := "22 Linda St."
locality := "Hoboken"
regionCode := "NJ"
postalCode := "07030"
countryCode := "US"
address := sleet.BillingAddress{
StreetAddress1: &streetAddress,
Locality: &locality,
RegionCode: ®ionCode,
PostalCode: &postalCode,
CountryCode: &countryCode,
}
// To get specific response headers, add them to the request options.
// They will be attached to the AuthorizationResponse
options := make(map[string]interface{})
options["ResponseHeader"] = []string{"x-test-header"}
authorizeRequest := sleet.AuthorizationRequest{
Amount: &amount,
CreditCard: &card,
BillingAddress: &address,
Options: options,
}
authorizeResponse, _ := client.Authorize(&authorizeRequest)
captureRequest := sleet.CaptureRequest{
Amount: &amount,
TransactionReference: authorizeResponse.TransactionReference,
}
client.Capture(&captureRequest)
Documentation
¶
Index ¶
- Constants
- func AmountToDecimalString(amount *Amount) string
- func AmountToString(amount *Amount) string
- func DefaultIfEmpty(primary string, fallback string) string
- func GetHTTPResponseHeader(options map[string]interface{}, httpResp http.Response) http.Header
- func TruncateString(str string, truncateLength int) string
- type AVSResponse
- type Address
- type Amount
- type AmountSplit
- type AuthorizationRequest
- type AuthorizationResponse
- type BillingAddress
- type CVVResponse
- type CaptureRequest
- type CaptureResponse
- type Client
- type ClientWithContext
- type CreditCard
- type CreditCardNetwork
- type Currency
- type Level3Data
- type LineItem
- type ProcessingInitiatorType
- type RTAUResponse
- type RTAUStatus
- type RefundRequest
- type RefundResponse
- type ResultType
- type ThreeDS
- type TokenType
- type TransactionDetailsRequest
- type TransactionDetailsResponse
- type VoidRequest
- type VoidResponse
Constants ¶
const ( // ResponseHeaderOption will return in the response the value for each HTTP header key listed in the option. // Value type: []string ResponseHeaderOption string = "ResponseHeader" // GooglePayTokenOption will use the provided Google Pay token to authorize the payment. // Value type: string GooglePayTokenOption string = "GooglePayToken" // ApplePayTokenOption will use the provided Apple Pay token to authorize the payment. // Value type: string ApplePayTokenOption string = "ApplePayToken" // CyberSourceTokenizeOption will cause tokens to be requested for each token type listed in the option. // Value type: []TokenType CyberSourceTokenizeOption string = "CyberSourceTokenize" )
const ( AuthCodeMetadata string = "authCode" ApprovalCodeMetadata string = "approvalCode" ResponseCodeMetadata string = "responseCode" )
const (
ThreedsStatusRejected = "R"
)
3DS response codes.
Variables ¶
This section is empty.
Functions ¶
func AmountToDecimalString ¶ added in v1.1.430
AmountToDecimalString converts an int64 amount in cents to a 2 decimal formatted string Note this function assumes 1 dollar = 100 cents (which is true for USD, CAD, etc but not true for some other currencies).
func AmountToString ¶
AmountToString converts an integer amount to a string with no formatting
func DefaultIfEmpty ¶ added in v1.1.550
DefaultIfEmpty returns the fallback string if str is an empty string.
func GetHTTPResponseHeader ¶ added in v1.1.1190
GetHTTPResponseHeader returns the http response headers specified in the given options.
func TruncateString ¶ added in v1.1.550
TruncateString returns a prefix of str of length truncateLength or all of str if truncateLength is greater than len(str)
Types ¶
type AVSResponse ¶ added in v1.0.225
type AVSResponse int
AVSResponse represents a possible Address Verification System response.
const ( AVSResponseUnknown AVSResponse = iota AVSResponseError // The AVS is unavailable due to a system error. AVSResponseUnsupported // The issuing bank does not support AVS. AVSResponseSkipped // Verification was not performed for this transaction. AVSResponseZip9MatchAddressMatch // 9-digit ZIP matches, street address matches. AVSResponseZip9MatchAddressNoMatch // 9-digit ZIP matches, street address doesn't match. AVSResponseZip5MatchAddressMatch // 5-digit ZIP matches, street address matches. AVSResponseZip5MatchAddressNoMatch // 5-digit ZIP matches, street address doesn't match. AVSresponseZipMatchAddressMatch // 5 or 9 digit ZIP matches, street address matches. AVSResponseZipNoMatchAddressMatch // ZIP doesn't match, street address matches. AVSResponseZipMatchAddressUnverified // ZIP matches, street address not verified. AVSResponseZipUnverifiedAddressMatch // ZIP not verified, street address matches. AVSResponseMatch // Generic "everything matches" AVSResponseNoMatch // Generic "nothing matches" AVSResponseNonUsZipMatchAddressMatch // (Non U.S. cards) ZIP matches, street address matches. AVSResponseNonUsZipNoMatchAddressNoMatch // (Non U.S. cards) ZIP and street address don't match. AVSResponseNonUsZipUnverifiedAddressMatch // (Non U.S. cards) ZIP unverified, street address matches. AVSResponseNameNoMatch // Cardholder's name doesn't match. AVSResponseNameNoMatchAddressMatch // Cardholder's name doesn't match, street address matches. AVSResponseNameNoMatchZipMatch // Cardholder's name doesn't match but ZIP code matches AVSResponseNameNoMatchZipMatchAddressMatch // Cardholder's name doesn't match but both zip/address do match AVSResponseNameMatchZipMatchAddressNoMatch // Cardholder's name and ZIP match, street address doesn't match. AVSResponseNameMatchZipNoMatchAddressMatch // Cardholder's name and street address match, ZIP doesn't match. AVSResponseNameMatchZipNoMatchAddressNoMatch // Cardholder's name matches, ZIP and street address don't match. AVSResponseNameMatchZipMatchAddressMatch // Cardholder's name, zip, and address all match )
Consts representing the various AVSResponses we can get We keep this pretty general to translate into any of our PsPs we support
func (AVSResponse) String ¶ added in v1.0.225
func (code AVSResponse) String() string
String returns a string representation of a AVS response code
type Address ¶ added in v1.1.857
type Address struct { StreetAddress1 *string StreetAddress2 *string Locality *string RegionCode *string PostalCode *string CountryCode *string // ISO 2-digit code Company *string Email *string PhoneNumber *string }
Address generic address to represent billing address, shipping address, etc. used for AVS checks for auth calls
type AmountSplit ¶ added in v1.1.1370
AmountSplit represents a split of the total transaction amount that should be routed to a specific account This is mostly used under Payfac models where we have different sub-accounts for merchants under a single platform account The platform commission is taken out of the split amount and routed to the platform account
type AuthorizationRequest ¶
type AuthorizationRequest struct { Amount Amount BillingAddress *Address Channel string // for PSPs that track the sales channel ClientTransactionReference *string // Custom transaction reference metadata that will be associated with this request CreditCard *CreditCard Cryptogram string // for Network Tokenization methods ECI string // E-Commerce Indicator (can be used for Network Tokenization as well) Level3Data *Level3Data MerchantOrderReference string // Similar to ClientTransactionReference but specifically if we want to store the shopping cart order id PreviousExternalTransactionID *string // If we are in a recurring situation, then we can use the PreviousExternalTransactionID as part of the auth request ProcessingInitiator *ProcessingInitiatorType // For Card on File transactions we want to store the various different types (initial cof, initial recurring, etc) ShippingAddress *Address ShopperReference string // ShopperReference Unique reference to a shopper (shopperId, etc.) ThreeDS *ThreeDS AmountSplits []AmountSplit Options map[string]interface{} }
AuthorizationRequest specifies needed information for request to authorize by PsPs Note: Only credit cards are supported Note: Options is a generic key-value pair that can be used to provide additional information to PsP
type AuthorizationResponse ¶
type AuthorizationResponse struct { // Success is true if Auth went through successfully Success bool TransactionReference string ExternalTransactionID string AvsResult AVSResponse CvvResult CVVResponse Response string ErrorCode string // Message is from the gateway describing the reason for the response code, for example a failed auth. Message string ResultType ResultType AvsResultRaw string CvvResultRaw string RTAUResult *RTAUResponse // AdyenAdditionalData stores additional recurring info (will be refactored to general naming on next major version upgrade) AdyenAdditionalData map[string]string // Metadata stores additional data that might be unique to PSP. Metadata map[string]string // CreatedTokens stores the tokens that were created as a result of the request, if any. CreatedTokens map[TokenType]string // StatusCode is the HTTP status code from the header of the PSP response. StatusCode int // Header is the HTTP header from the PSP response, filtered by the list of headers in the ResponseHeaderOption. Header http.Header }
AuthorizationResponse is a generic response returned back to client after data massaging from PsP Response. The raw AVS and CVV are included if applicable. Raw fields contain the untranslated responses from processors, while the non-raw fields are the best parsings to a single standard, with loss of granularity minimized. The latter should be preferred when treating Sleet as a black box.
type CVVResponse ¶ added in v1.0.225
type CVVResponse int
CVVResponse represents a possible CVV/CVN verification response.
const ( CVVResponseUnknown CVVResponse = iota // Unknown CVV code returned by processor CVVResponseNoResponse // No verification response was given CVVResponseError // An error prevented verification (e.g. data validation check failed) CVVResponseUnsupported // CVV verification is not supported CVVResponseMatch // CVV matches CVVResponseNoMatch // CVV doesn't match CVVResponseNotProcessed // Verification didn't happen (e.g. auth already declined by bank before checking CVV) CVVResponseRequiredButMissing // CVV should be present, but it was reported as not CVVResponseSuspicious // The issuing bank determined this transaction to be suspicious CVVResponseSkipped // Verification was not performed for this transaction )
Enum representing general CVV responses that we have
func (CVVResponse) String ¶ added in v1.0.225
func (code CVVResponse) String() string
String returns a string representation of a CVV response code
type CaptureRequest ¶
type CaptureRequest struct { Amount *Amount TransactionReference string ClientTransactionReference *string // Custom transaction reference metadata that will be associated with this request MerchantOrderReference *string // Custom merchant order reference that will be associated with this request Options map[string]interface{} // For additional options that need to be passed in AmountSplits []AmountSplit }
CaptureRequest specifies the authorized transaction to capture and also an amount for partial capture use cases
type CaptureResponse ¶
CaptureResponse will have Success be true if transaction is captured and also a reference to be used for subsequent operations
type Client ¶
type Client interface { Authorize(request *AuthorizationRequest) (*AuthorizationResponse, error) Capture(request *CaptureRequest) (*CaptureResponse, error) Void(request *VoidRequest) (*VoidResponse, error) Refund(request *RefundRequest) (*RefundResponse, error) }
Client defines the Sleet interface which takes in a generic request and returns a generic response The translations for each specific PsP takes place in the corresponding gateways/<PsP> folders The four supported methods are Auth, Capture, Void, Refund
type ClientWithContext ¶ added in v1.1.1297
type ClientWithContext interface { Client // supset includes the normal Client interface AuthorizeWithContext(ctx context.Context, request *AuthorizationRequest) (*AuthorizationResponse, error) CaptureWithContext(ctx context.Context, request *CaptureRequest) (*CaptureResponse, error) VoidWithContext(ctx context.Context, request *VoidRequest) (*VoidResponse, error) RefundWithContext(ctx context.Context, request *RefundRequest) (*RefundResponse, error) }
ClientWithContext is a superset of `Client` that includes addtional methods that take `context.Context` as parameters.
type CreditCard ¶
type CreditCard struct { FirstName string LastName string Number string ExpirationMonth int ExpirationYear int CVV string Network CreditCardNetwork Save bool // indicates if customer wants to save their credit card details }
CreditCard represents raw credit card information
type CreditCardNetwork ¶ added in v1.1.463
type CreditCardNetwork int
CreditCardNetwork card network (eg visa)
const ( // CreditCardNetworkUnknown unknown network CreditCardNetworkUnknown CreditCardNetwork = iota // CreditCardNetworkVisa visa CreditCardNetworkVisa // CreditCardNetworkMastercard mastercard CreditCardNetworkMastercard // CreditCardNetworkAmex amex CreditCardNetworkAmex // CreditCardNetworkDiscover discover CreditCardNetworkDiscover // CreditCardNetworkJcb JCBP CreditCardNetworkJcb // CreditCardNetworkUnionpay UnionPay CreditCardNetworkUnionpay // CreditCardNetworkCitiPLCC citiplcc CreditCardNetworkCitiPLCC )
type Currency ¶ added in v1.0.310
Currency maps to the CURRENCIES list in currency.go specifying the symbol and precision for the currency
type Level3Data ¶
type Level3Data struct { CustomerReference string TaxAmount Amount DiscountAmount Amount ShippingAmount Amount DutyAmount Amount DestinationPostalCode string DestinationCountryCode string DestinationAdminArea string LineItems []LineItem }
Level3Data contains all of the information needed for Level3 processing including LineItems
type LineItem ¶
type LineItem struct { Description string ProductCode string UnitPrice Amount Quantity int64 TotalAmount Amount ItemTaxAmount Amount ItemDiscountAmount Amount UnitOfMeasure string CommodityCode string }
LineItem is used for Level3 Processing if enabled (not default). Specifies information per item in the order
type ProcessingInitiatorType ¶ added in v1.1.507
type ProcessingInitiatorType string
ProcessingInitiatorType type of processing initiator
const ( // ProcessingInitiatorTypeInitialCardOnFile initial non-recurring payment ProcessingInitiatorTypeInitialCardOnFile ProcessingInitiatorType = "initial_card_on_file" // ProcessingInitiatorTypeInitialRecurring initiating recurring payment ProcessingInitiatorTypeInitialRecurring ProcessingInitiatorType = "initial_recurring" // ProcessingInitiatorTypeStoredCardholderInitiated initiated by cardholder using stored card ProcessingInitiatorTypeStoredCardholderInitiated ProcessingInitiatorType = "stored_cardholder_initiated" // ProcessingInitiatorTypeStoredMerchantInitiated initiated by merchant using stored card ProcessingInitiatorTypeStoredMerchantInitiated ProcessingInitiatorType = "stored_merchant_initiated" // ProcessingInitiatorTypeFollowingRecurring recurring payment ProcessingInitiatorTypeFollowingRecurring ProcessingInitiatorType = "following_recurring" )
type RTAUResponse ¶ added in v1.1.679
type RTAUResponse struct { RealTimeAccountUpdateStatus RTAUStatus UpdatedExpiry *time.Time UpdatedBIN string UpdatedLast4 string }
type RTAUStatus ¶ added in v1.1.670
type RTAUStatus string
RTAUStatus represents the Real Time Account Updater response from a processor, if applicable
const ( RTAUStatusUnknown RTAUStatus = "Unknown" // when a processor has RTAU capability, but returns an unexpected status RTAUStatusNoResponse RTAUStatus = "NoResponse" // when a processor has RTAU capability, but doesn't return any additional info RTAUStatusCardChanged RTAUStatus = "CardChanged" RTAUStatusCardExpired RTAUStatus = "CardExpiryChanged" RTAUStatusContactCardAccountHolder RTAUStatus = "ContactCardAccountHolder" RTAUStatusCloseAccount RTAUStatus = "CloseAccount" )
type RefundRequest ¶
type RefundRequest struct { Amount *Amount TransactionReference string ClientTransactionReference *string // Custom transaction reference metadata that will be associated with this request MerchantOrderReference *string // Custom merchant order reference that will be associated with this request Last4 string Options map[string]interface{} AmountSplits []AmountSplit }
RefundRequest for refunding a captured transaction with generic Options and amount to be refunded
type RefundResponse ¶
RefundResponse indicating if request went through successfully
type ResultType ¶ added in v1.1.1338
type ResultType string
const ( ResultTypeSuccess ResultType = "Approved" ResultTypeUnknownError ResultType = "Unknown" ResultTypePaymentError ResultType = "PaymentError" // payment or credit card related error ResultTypeAPIError ResultType = "APIError" // error related to the PSPs API (validation error, authentication, idempotency, etc) ResultTypeServerError ResultType = "ServerError" // network, connection, timeout etc. errors )
type ThreeDS ¶ added in v1.1.846
type ThreeDS struct { Frictionless bool // Whether the 3DS flow for this transaction was frictionless ACSTransactionID string // Transaction ID assigned by ACS CAVV string // Cardholder Authentication Value CAVVAlgorithm string // Algorithm used to calculate CAVV DSTransactionID string // Directory Server (DS) Transaction ID (for 3DS2) PAResStatus string // Transaction status result UCAFIndicator string // Universal Cardholder Authentication Field Indicator value provided by issuer Version string // 3DS Version XID string // Transaction ID from authentication processing (for 3DS1) }
ThreeDS holds results from a 3DS verification challenge.
type TokenType ¶ added in v1.1.1365
type TokenType string
TokenType defines the type of token, used either as input to complete a transaction, or as output to be saved for future transactions.
const ( // TokenTypeCustomer points to a token that can be mapped to information about a customer. // Examples of mapped data: name + shipping address + list of preferred payment methods. TokenTypeCustomer TokenType = "customerToken" // TokenTypePayment points to a token that can be mapped to information about a payment method and its auxiliary data. // Examples of mapped data: payment account number + expiration + billing address. TokenTypePayment TokenType = "paymentToken" // TokenTypePaymentIdentifier points to a token that can be mapped to only a payment account number. TokenTypePaymentIdentifier TokenType = "paymentIdentifierToken" // TokenTypeShippingAddress points to a token that can be mapped to a shipping address. TokenTypeShippingAddress TokenType = "shippingAddressToken" )
type TransactionDetailsRequest ¶ added in v1.1.1362
type TransactionDetailsRequest struct {
TransactionReference string
}
TransactionDetailsRequest for fetching a transaction's details
type TransactionDetailsResponse ¶ added in v1.1.1362
TransactionDetailsResponse indicating the transaction details. Currently, only the last 4 digits of credit card is returned.
type VoidRequest ¶
type VoidRequest struct { TransactionReference string ClientTransactionReference *string // Custom transaction reference metadata that will be associated with this request MerchantOrderReference *string // Custom merchant order reference that will be associated with this request }
VoidRequest cancels an authorized transaction
type VoidResponse ¶
VoidResponse also specifies a transaction reference if PsP uses different transaction references for different states