Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Commit

Permalink
add customer ip to authnet options (#240)
Browse files Browse the repository at this point in the history
* add customer ip

* fix nil pointer in test

* fix unit test
  • Loading branch information
rlcooper46 authored Jul 11, 2022
1 parent c37d902 commit d8463aa
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 53 deletions.
53 changes: 36 additions & 17 deletions gateways/authorizenet/request_builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ const (
InvoiceNumberMaxLength = 20
)

// Options
const (
customerIPOption = "CustomerIP" // Pass as a string pointer
)

func buildAuthRequest(merchantName string, transactionKey string, authRequest *sleet.AuthorizationRequest) *Request {
amountStr := sleet.AmountToDecimalString(&authRequest.Amount)
billingAddress := authRequest.BillingAddress
Expand All @@ -39,13 +44,13 @@ func buildAuthRequest(merchantName string, transactionKey string, authRequest *s
CreditCard: creditCard,
},
BillingAddress: &BillingAddress{
FirstName: authRequest.CreditCard.FirstName,
LastName: authRequest.CreditCard.LastName,
Address: billingAddress.StreetAddress1,
City: billingAddress.Locality,
State: billingAddress.RegionCode,
Zip: billingAddress.PostalCode,
Country: billingAddress.CountryCode,
FirstName: authRequest.CreditCard.FirstName,
LastName: authRequest.CreditCard.LastName,
Address: billingAddress.StreetAddress1,
City: billingAddress.Locality,
State: billingAddress.RegionCode,
Zip: billingAddress.PostalCode,
Country: billingAddress.CountryCode,
PhoneNumber: billingAddress.PhoneNumber,
},
Customer: &Customer{
Expand All @@ -61,6 +66,14 @@ func buildAuthRequest(merchantName string, transactionKey string, authRequest *s

authorizeRequest = *addL2L3Data(authRequest, &authorizeRequest)

// Pass customer ip if included in options map
if authRequest.Options[customerIPOption] != nil {
customerIp, ok := authRequest.Options[customerIPOption].(*string)
if ok {
authorizeRequest.TransactionRequest.CustomerIP = customerIp
}
}

return &Request{CreateTransactionRequest: authorizeRequest}
}

Expand Down Expand Up @@ -91,7 +104,10 @@ func buildCaptureRequest(merchantName string, transactionKey string, captureRequ
return request
}

func buildRefundRequest(merchantName string, transactionKey string, refundRequest *sleet.RefundRequest) (*Request, error) {
func buildRefundRequest(merchantName string, transactionKey string, refundRequest *sleet.RefundRequest) (
*Request,
error,
) {
amountStr := sleet.AmountToDecimalString(refundRequest.Amount)
request := &Request{
CreateTransactionRequest: CreateTransactionRequest{
Expand Down Expand Up @@ -131,7 +147,10 @@ func authentication(merchantName string, transactionKey string) MerchantAuthenti
}
}

func addL2L3Data(authRequest *sleet.AuthorizationRequest, authNetAuthRequest *CreateTransactionRequest) *CreateTransactionRequest {
func addL2L3Data(
authRequest *sleet.AuthorizationRequest,
authNetAuthRequest *CreateTransactionRequest,
) *CreateTransactionRequest {
if authRequest.Level3Data != nil {
lineItemString := buildLineItemsString(authRequest)
if lineItemString != nil {
Expand Down Expand Up @@ -161,14 +180,14 @@ func addL2L3Data(authRequest *sleet.AuthorizationRequest, authNetAuthRequest *Cr

if authRequest.ShippingAddress != nil {
authNetAuthRequest.TransactionRequest.ShippingAddress = &ShippingAddress{
FirstName: authRequest.CreditCard.FirstName,
LastName: authRequest.CreditCard.LastName,
Company: common.SafeStr(authRequest.ShippingAddress.Company),
Address: authRequest.ShippingAddress.StreetAddress1,
City: authRequest.ShippingAddress.Locality,
State: authRequest.ShippingAddress.RegionCode,
Zip: authRequest.ShippingAddress.PostalCode,
Country: authRequest.ShippingAddress.CountryCode,
FirstName: authRequest.CreditCard.FirstName,
LastName: authRequest.CreditCard.LastName,
Company: common.SafeStr(authRequest.ShippingAddress.Company),
Address: authRequest.ShippingAddress.StreetAddress1,
City: authRequest.ShippingAddress.Locality,
State: authRequest.ShippingAddress.RegionCode,
Zip: authRequest.ShippingAddress.PostalCode,
Country: authRequest.ShippingAddress.CountryCode,
}
}

Expand Down
74 changes: 60 additions & 14 deletions gateways/authorizenet/request_builders_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build unit
// +build unit

package authorizenet
Expand Down Expand Up @@ -26,6 +27,14 @@ func TestBuildAuthRequest(t *testing.T) {
baseL2L3MultipleItems.Level3Data = sleet_testing.BaseLevel3DataMultipleItem()
baseL2L3MultipleItems.ShippingAddress = baseL2L3MultipleItems.BillingAddress

withCustomerIP := sleet_testing.BaseAuthorizationRequestWithEmailPhoneNumber()
withCustomerIP.MerchantOrderReference = randomdata.Alphanumeric(InvoiceNumberMaxLength + 5)
customerIP := common.SPtr("192.168.0.1")
if withCustomerIP.Options == nil {
withCustomerIP.Options = make(map[string]interface{})
}
withCustomerIP.Options[customerIPOption] = customerIP

amount := "1.00"
cases := []struct {
label string
Expand All @@ -49,13 +58,13 @@ func TestBuildAuthRequest(t *testing.T) {
},
},
BillingAddress: &BillingAddress{
FirstName: "Bolt",
LastName: "Checkout",
Address: base.BillingAddress.StreetAddress1,
City: base.BillingAddress.Locality,
State: base.BillingAddress.RegionCode,
Zip: base.BillingAddress.PostalCode,
Country: base.BillingAddress.CountryCode,
FirstName: "Bolt",
LastName: "Checkout",
Address: base.BillingAddress.StreetAddress1,
City: base.BillingAddress.Locality,
State: base.BillingAddress.RegionCode,
Zip: base.BillingAddress.PostalCode,
Country: base.BillingAddress.CountryCode,
PhoneNumber: base.BillingAddress.PhoneNumber,
},
Order: &Order{
Expand Down Expand Up @@ -92,13 +101,13 @@ func TestBuildAuthRequest(t *testing.T) {
},
},
BillingAddress: &BillingAddress{
FirstName: "Bolt",
LastName: "Checkout",
Address: base.BillingAddress.StreetAddress1,
City: base.BillingAddress.Locality,
State: base.BillingAddress.RegionCode,
Zip: base.BillingAddress.PostalCode,
Country: base.BillingAddress.CountryCode,
FirstName: "Bolt",
LastName: "Checkout",
Address: base.BillingAddress.StreetAddress1,
City: base.BillingAddress.Locality,
State: base.BillingAddress.RegionCode,
Zip: base.BillingAddress.PostalCode,
Country: base.BillingAddress.CountryCode,
PhoneNumber: base.BillingAddress.PhoneNumber,
},
Customer: &Customer{
Expand Down Expand Up @@ -218,6 +227,43 @@ func TestBuildAuthRequest(t *testing.T) {
},
},
},
{
"Basic Auth Request with customer IP",
withCustomerIP,
&Request{
CreateTransactionRequest: CreateTransactionRequest{
MerchantAuthentication: MerchantAuthentication{Name: "MerchantName", TransactionKey: "Key"},
TransactionRequest: TransactionRequest{
TransactionType: TransactionTypeAuthOnly,
Amount: &amount,
Payment: &Payment{
CreditCard: CreditCard{
CardNumber: "4111111111111111",
ExpirationDate: "2023-10",
CardCode: withCustomerIP.CreditCard.CVV,
},
},
BillingAddress: &BillingAddress{
FirstName: "Bolt",
LastName: "Checkout",
Address: withCustomerIP.BillingAddress.StreetAddress1,
City: withCustomerIP.BillingAddress.Locality,
State: withCustomerIP.BillingAddress.RegionCode,
Zip: withCustomerIP.BillingAddress.PostalCode,
Country: withCustomerIP.BillingAddress.CountryCode,
PhoneNumber: withCustomerIP.BillingAddress.PhoneNumber,
},
Order: &Order{
InvoiceNumber: withCustomerIP.MerchantOrderReference[:InvoiceNumberMaxLength],
},
Customer: &Customer{
Email: *withCustomerIP.BillingAddress.Email,
},
CustomerIP: customerIP,
},
},
},
},
}

for _, c := range cases {
Expand Down
41 changes: 21 additions & 20 deletions gateways/authorizenet/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,20 @@ type MerchantAuthentication struct {
// *************************************************************************
// *************************************************************************
type TransactionRequest struct {
TransactionType TransactionType `json:"transactionType"`
Amount *string `json:"amount,omitempty"`
Payment *Payment `json:"payment,omitempty"`
RefTransactionID *string `json:"refTransId,omitempty"`
Order *Order `json:"order,omitempty"`
LineItem json.RawMessage `json:"lineItems,omitempty"` // this is really a repeating LineItem, but authorize.net expects it in object not array
TransactionType TransactionType `json:"transactionType"`
Amount *string `json:"amount,omitempty"`
Payment *Payment `json:"payment,omitempty"`
RefTransactionID *string `json:"refTransId,omitempty"`
Order *Order `json:"order,omitempty"`
LineItem json.RawMessage `json:"lineItems,omitempty"` // this is really a repeating LineItem, but authorize.net expects it in object not array
// since not valid json, just going to represent as JSON string
Tax *Tax `json:"tax,omitempty"`
Duty *Tax `json:"duty,omitempty"`
Shipping *Tax `json:"shipping,omitempty"`
Customer *Customer `json:"customer,omitempty"`
BillingAddress *BillingAddress `json:"billTo,omitempty"`
ShippingAddress *ShippingAddress `json:"shipTo,omitempty"`
Tax *Tax `json:"tax,omitempty"`
Duty *Tax `json:"duty,omitempty"`
Shipping *Tax `json:"shipping,omitempty"`
Customer *Customer `json:"customer,omitempty"`
BillingAddress *BillingAddress `json:"billTo,omitempty"`
ShippingAddress *ShippingAddress `json:"shipTo,omitempty"`
CustomerIP *string `json:"customerIP,omitempty"`
}

type LineItem struct {
Expand Down Expand Up @@ -176,14 +177,14 @@ type ShippingAddress struct {

// BillingAddress is used in TransactionRequest for making an auth call
type BillingAddress struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Company string `json:"company"`
Address *string `json:"address"`
City *string `json:"city"`
State *string `json:"state"`
Zip *string `json:"zip"`
Country *string `json:"country"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Company string `json:"company"`
Address *string `json:"address"`
City *string `json:"city"`
State *string `json:"state"`
Zip *string `json:"zip"`
Country *string `json:"country"`
PhoneNumber *string `json:"phoneNumber"`
}

Expand Down
23 changes: 21 additions & 2 deletions integration-tests/authorizenet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ func TestAuthNetAuthL2L3MultipleItem(t *testing.T) {
}
}

func TestAuthNetAuthWithCustomerIP(t *testing.T) {
client := authorizenet.NewClient(getEnv("AUTH_NET_LOGIN_ID"), getEnv("AUTH_NET_TXN_KEY"), common.Sandbox)
authRequest := sleet_testing.BaseAuthorizationRequestWithEmailPhoneNumber()
if authRequest.Options == nil {
authRequest.Options = make(map[string]interface{})
}
authRequest.Options["CustomerIP"] = sPtr("192.168.0.1")
authRequest.Amount.Amount = int64(randomdata.Number(100))
authRequest.MerchantOrderReference = "test-order-ref"
auth, err := client.Authorize(authRequest)
if err != nil {
t.Error("Authorize request should not have failed")
}

if !auth.Success {
t.Error("Resulting auth should have been successful")
}
}

// TestAuthNetRechargeAuth
//
// Recharge requests will not have CVV. This should successfully create an authorization on Authorize.net
Expand Down Expand Up @@ -203,8 +222,8 @@ func TestAuthNetAuthCaptureRefund(t *testing.T) {
// Refunds for AuthNet take 24 hours to settle. The only option for immediate testing is to do a non-transaction
// referenced refund. We will send full credit card number
refundRequest := &sleet.RefundRequest{
Amount: &authRequest.Amount,
Last4: authRequest.CreditCard.Number,
Amount: &authRequest.Amount,
Last4: authRequest.CreditCard.Number,
MerchantOrderReference: common.SPtr(randomdata.Digits(16)),
Options: map[string]interface{}{
"TestingExpirationOverride": fmt.Sprintf("%d%d", authRequest.CreditCard.ExpirationMonth, authRequest.CreditCard.ExpirationYear),
Expand Down

0 comments on commit d8463aa

Please sign in to comment.