Skip to content

Commit

Permalink
Bump version to 2.20.1
Browse files Browse the repository at this point in the history
  • Loading branch information
devops-blockchyp committed Nov 20, 2024
1 parent 4db8579 commit 4ad9adc
Show file tree
Hide file tree
Showing 9 changed files with 1,163 additions and 17 deletions.
143 changes: 142 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,80 @@ func voidExample() {

```

#### Card Metadata



* **API Credential Types:** Merchant
* **Required Role:** Payment API Access

This API allows you to retrieve card metadata.

Card metadata requests can use a payment terminal to retrieve metadata or
use a previously enrolled payment token.

**Terminal Transactions**

For terminal transactions, make sure you pass in the terminal name using the `terminalName` property.

**Token Transactions**

If you have a payment token, omit the `terminalName` property and pass in the token with the `token`
property instead.

**Card Numbers and Mag Stripes**

You can also pass in PANs and Mag Stripes, but you probably shouldn't, as this will
put you in PCI scope and the most common vector for POS breaches is keylogging.
If you use terminals for manual card entry, you'll bypass any keyloggers that
might be maliciously running on the point-of-sale system.




```go
package main

import (
"fmt"
"log"

blockchyp "github.com/blockchyp/blockchyp-go/v2"
)

func cardMetadataExample() {
// sample credentials
creds := blockchyp.APICredentials{
APIKey: "ZDSMMZLGRPBPRTJUBTAFBYZ33Q",
BearerToken: "ZLBW5NR4U5PKD5PNP3ZP3OZS5U",
SigningKey: "9c6a5e8e763df1c9256e3d72bd7f53dfbd07312938131c75b3bfd254da787947",
}

// instantiate the client
client := blockchyp.NewClient(creds)

// setup request object
request := blockchyp.CardMetadataRequest{
Test: true,
TerminalName: "Test Terminal",
}

response, err := client.CardMetadata(request)

if err != nil {
log.Fatal(err)
}

//process the result
if response.Success {
fmt.Println("success")
}

fmt.Printf("Response: %+v\n", response)
}

```

#### Time Out Reversal


Expand Down Expand Up @@ -5858,7 +5932,9 @@ func merchantCredentialGenerationExample() {
client := blockchyp.NewClient(creds)

// setup request object
request := blockchyp.MerchantCredentialGenerationRequest{}
request := blockchyp.MerchantCredentialGenerationRequest{
MerchantID: "<MERCHANT ID>",
}

response, err := client.MerchantCredentialGeneration(request)

Expand All @@ -5876,6 +5952,71 @@ func merchantCredentialGenerationExample() {

```

#### Submit Application



* **API Credential Types:** Partner
* **Required Role:** INVITE MERCHANT

This is a partner level API that can be used to submit applications to add new merchant accounts. The application requires a significant amount of detailed information about the merchant and their business. Rather than providing an exhaustive list of required fields, we recommend submitting as much information as possible in your initial request.

If any required fields are missing or if there are any validation errors, the API will return specific error messages indicating which fields need to be addressed. Simply review these validation errors, fill in the missing information or correct any errors, and resubmit the application.

Key areas of information include:
- Business details (name, type, tax information)
- Contact information
- Address information (physical and mailing)
- Owner details
- Bank account information
- Transaction volume estimates
- Operational settings (timezone, batch close time, etc.)

**Note:** Some fields may be conditionally required based on the values of other fields. The validation process will guide you through ensuring all necessary information is provided.




```go
package main

import (
"fmt"
"log"

blockchyp "github.com/blockchyp/blockchyp-go/v2"
)

func submitApplicationExample() {
// sample credentials
creds := blockchyp.APICredentials{
APIKey: "ZDSMMZLGRPBPRTJUBTAFBYZ33Q",
BearerToken: "ZLBW5NR4U5PKD5PNP3ZP3OZS5U",
SigningKey: "9c6a5e8e763df1c9256e3d72bd7f53dfbd07312938131c75b3bfd254da787947",
}

// instantiate the client
client := blockchyp.NewClient(creds)

// setup request object
request := blockchyp.SubmitApplicationRequest{}

response, err := client.SubmitApplication(request)

if err != nil {
log.Fatal(err)
}

//process the result
if response.Success {
fmt.Println("Success")
}

fmt.Printf("Response: %+v\n", response)
}

```




Expand Down
62 changes: 62 additions & 0 deletions blockchyp.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,53 @@ func (client *Client) Enroll(request EnrollRequest) (*EnrollResponse, error) {
return &response, err
}

// CardMetadata retrieves card metadata.
func (client *Client) CardMetadata(request CardMetadataRequest) (*CardMetadataResponse, error) {
var response CardMetadataResponse
var err error

if err := populateSignatureOptions(&request); err != nil {
return nil, err
}

if request.TerminalName != "" {
var route TerminalRoute
route, err = client.resolveTerminalRoute(request.TerminalName)
if err != nil {
if errors.Is(err, ErrUnknownTerminal) {
response.ResponseDescription = ResponseUnknownTerminal
return &response, err
}

return nil, err
}

if route.CloudRelayEnabled {
err = client.RelayRequest("/api/card-metadata", "POST", request, &response, request.Test, request.Timeout)
} else {
authRequest := TerminalCardMetadataRequest{
APICredentials: route.TransientCredentials,
Request: request,
}
err = client.terminalRequest(route, "/api/card-metadata", "POST", authRequest, &response, request.Timeout)
}
} else {
err = client.GatewayRequest("/api/card-metadata", "POST", request, &response, request.Test, request.Timeout)
}

if timeout, ok := err.(net.Error); ok && timeout.Timeout() {
response.ResponseDescription = ResponseTimedOut
} else if err != nil {
response.ResponseDescription = err.Error()
}

if err := handleSignature(request, &response); err != nil {
log.Printf("Failed to write signature: %+v", err)
}

return &response, err
}

// GiftActivate activates or recharges a gift card.
func (client *Client) GiftActivate(request GiftActivateRequest) (*GiftActivateResponse, error) {
var response GiftActivateResponse
Expand Down Expand Up @@ -1493,6 +1540,21 @@ func (client *Client) MerchantCredentialGeneration(request MerchantCredentialGen
return &response, err
}

// SubmitApplication submits and application to add a new merchant account.
func (client *Client) SubmitApplication(request SubmitApplicationRequest) (*Acknowledgement, error) {
var response Acknowledgement

err := client.DashboardRequest("/api/submit-application", "POST", request, &response, request.Timeout)

if err, ok := err.(net.Error); ok && err.Timeout() {
response.ResponseDescription = ResponseTimedOut
} else if err != nil {
response.ResponseDescription = err.Error()
}

return &response, err
}

// GetMerchants adds a test merchant account.
func (client *Client) GetMerchants(request GetMerchantsRequest) (*GetMerchantsResponse, error) {
var response GetMerchantsResponse
Expand Down
4 changes: 4 additions & 0 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ type CommandLineArguments struct {
DeleteProtected bool `json:"deteleProtected"`
Roles string `json:"roles"`
Notes string `json:"notes"`
Healthcare bool `json:"healthcare"`
HealthcareTotal string `json:"healthcareTotal"`
EBTTotal string `json:"ebtTotal"`
CardMetadataLookup bool `json:"cardMetadataLookup"`
CredType string `json:"credType"`
}

Expand Down
93 changes: 84 additions & 9 deletions cmd/blockchyp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,24 +186,28 @@ func parseArgs() blockchyp.CommandLineArguments {
flag.BoolVar(&args.Incremental, "incremental", false, "force incremental firmware downloads")
flag.BoolVar(&args.ChipRejection, "chipRejection", false, "simulates a chip rejection")
flag.BoolVar(&args.OutOfOrderReversal, "outOfOrderReversal", false, "simulates an out of order auto reversal")
flag.BoolVar(&args.AsyncReversals, "asyncReversals", false, "causes auto-reversals to run asynchronously")
flag.BoolVar(&args.AsyncReversals, "asyncReversals", false, "causes auto-reversals to run asynchronously.")
flag.BoolVar(&args.CardOnFile, "cardOnFile", false, "flags a transaction as MOTO / card on file.")
flag.BoolVar(&args.Recurring, "recurring", false, "flags a transaction as recurring.")
flag.BoolVar(&args.MIT, "mit", false, "manually sets the MIT flag.")
flag.BoolVar(&args.CIT, "cit", false, "manually sets the CIT flag.")
flag.BoolVar(&args.Subscription, "subscription", false, "flags a transaction as a subscription.")
flag.StringVar(&args.PONumber, "po", "", "purchase order for L2 transactions")
flag.StringVar(&args.SupplierReferenceNumber, "srn", "", "supplier reference number for L2 transactions")
flag.StringVar(&args.PolicyID, "policy", "", "policy id for pricing policy related operations")
flag.StringVar(&args.StatementID, "statementId", "", "statement id for partner or merchant statement operations")
flag.StringVar(&args.InvoiceID, "invoiceId", "", "invoice id for partner or merchant statement/invoice operations")
flag.StringVar(&args.SupplierReferenceNumber, "srn", "", "supplier reference number for L2 transactions.")
flag.StringVar(&args.PolicyID, "policy", "", "policy id for pricing policy related operations.")
flag.StringVar(&args.StatementID, "statementId", "", "statement id for partner or merchant statement operations.")
flag.StringVar(&args.InvoiceID, "invoiceId", "", "invoice id for partner or merchant statement/invoice operations.")
flag.IntVar(&args.ShipmentNumber, "shipmentNumber", 0, "indicates the shipment number in a split shipment order.")
flag.IntVar(&args.ShipmentCount, "shipmentCount", 0, "indicates the total number of shipments in a split shipment order.")
flag.StringVar(&args.EntryMethod, "entryMethod", "", "is the method by which the payment card was entered.")
flag.BoolVar(&args.DeleteProtected, "deleteProtected", false, "protects the credentials from deletion")
flag.StringVar(&args.Roles, "roles", "", "an optional array of role codes that will be assigned to the credentials")
flag.StringVar(&args.Notes, "notes", "", "free form description of the purpose or intent behind the credentials")
flag.StringVar(&args.CredType, "credType", "", "is the type of credential to be generated, API or TOKENIZING")
flag.BoolVar(&args.DeleteProtected, "deleteProtected", false, "protects the credentials from deletion.")
flag.StringVar(&args.Roles, "roles", "", "an optional array of role codes that will be assigned to the credentials.")
flag.StringVar(&args.Notes, "notes", "", "free form description of the purpose or intent behind the credentials.")
flag.BoolVar(&args.Healthcare, "healthcare", false, "indicates this transaction is HSA/FSA")
flag.StringVar(&args.HealthcareTotal, "healthcareTotal", "", "total amount of healthcare")
flag.StringVar(&args.EBTTotal, "ebtTotal", "", "total amount of ebt")
flag.BoolVar(&args.CardMetadataLookup, "cardMetadataLookup", false, "requests card metatdata instead of enrolling a card.")
flag.StringVar(&args.CredType, "credType", "", "is the type of credential to be generated, API or TOKENIZING.")
flag.Parse()

if args.Version {
Expand Down Expand Up @@ -476,6 +480,10 @@ func processCommand(args blockchyp.CommandLineArguments) {
processUnlinkToken(client, args)
case "drop-terminal-socket":
processDropSocket(client, args)
case "card-metadata":
processCardMetadata(client, args)
case "submit-application":
processSubmitApplication(client, args)
default:
fatalErrorf("unknown command: %s", cmd)
}
Expand Down Expand Up @@ -1613,6 +1621,7 @@ func processRefund(client *blockchyp.Client, args blockchyp.CommandLineArguments
PAN: args.PAN,
ExpMonth: args.ExpiryMonth,
ExpYear: args.ExpiryYear,
CardMetadataLookup: args.CardMetadataLookup,
}

if args.Debit {
Expand Down Expand Up @@ -1830,6 +1839,7 @@ func processEnroll(client *blockchyp.Client, args blockchyp.CommandLineArguments
EntryMethod: args.EntryMethod,
Recurring: args.Recurring,
Subscription: args.Subscription,
CardMetadataLookup: args.CardMetadataLookup,
}
if hasCustomerFields(args) {
req.Customer = populateCustomer(args)
Expand Down Expand Up @@ -1905,6 +1915,10 @@ func processAuth(client *blockchyp.Client, args blockchyp.CommandLineArguments)
TransactionID: args.TransactionID,
PurchaseOrderNumber: args.PONumber,
SupplierReferenceNumber: args.SupplierReferenceNumber,
Healthcare: args.Healthcare,
HealthcareTotal: args.HealthcareTotal,
EBTTotal: args.EBTTotal,
CardMetadataLookup: args.CardMetadataLookup,
}

displayTx := assembleDisplayTransaction(args)
Expand Down Expand Up @@ -2747,6 +2761,67 @@ func processTokenDelete(client *blockchyp.Client, args blockchyp.CommandLineArgu
dumpResponse(&args, res)
}

func processCardMetadata(client *blockchyp.Client, args blockchyp.CommandLineArguments) {

req := &blockchyp.CardMetadataRequest{}

if !parseJSONInput(args, req) {

if (args.TerminalName == "") && (args.Token == "") && (args.PAN == "") {
fatalError("-terminal or -token requred")
}

req = &blockchyp.CardMetadataRequest{
Timeout: args.Timeout,
Test: args.Test,
TransactionRef: args.TransactionRef,
WaitForRemovedCard: args.WaitForRemovedCard,
Force: args.Force,
Token: args.Token,
PAN: args.PAN,
ExpMonth: args.ExpiryMonth,
ExpYear: args.ExpiryYear,
Address: args.Address,
PostalCode: args.PostalCode,
ManualEntry: args.ManualEntry,
TerminalName: args.TerminalName,
ResetConnection: args.ResetConnection,
}

if args.Debit {
req.CardType = blockchyp.CardTypeDebit
} else if args.EBT {
req.CardType = blockchyp.CardTypeEBT
}
}

res, err := client.CardMetadata(*req)

if err != nil {
handleError(&args, err)
}

dumpResponse(&args, res)
}

func processSubmitApplication(client *blockchyp.Client, args blockchyp.CommandLineArguments) {

request := &blockchyp.SubmitApplicationRequest{}

if !parseJSONInput(args, request) {
if (args.JSON == "") && args.JSONFile == "" {
fatalError("-json or -jsonFile required")
}
}

ack, err := client.SubmitApplication(*request)
if err != nil {
handleError(&args, err)
}

dumpResponse(&args, ack)
}

func parseTimestamp(ts string) (time.Time, error) {

parsedResult, err := parseTimestampWithFormat(ts, time.RFC3339)
Expand Down
Loading

0 comments on commit 4ad9adc

Please sign in to comment.