Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
A
authorizenetwebform
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Custom Issue Tracker
Custom Issue Tracker
Labels
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Analytics
Analytics
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
project
authorizenetwebform
Commits
13176d7e
Commit
13176d7e
authored
Nov 24, 2018
by
jenlampton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add recurring billing option, and required fields.
parent
9aeeca47
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
204 additions
and
72 deletions
+204
-72
INSTALL.txt
INSTALL.txt
+18
-3
authorizenetwebform.module
authorizenetwebform.module
+176
-60
authorizenetwebform_fields.inc
authorizenetwebform_fields.inc
+10
-9
No files found.
INSTALL.txt
View file @
13176d7e
...
...
@@ -46,9 +46,24 @@ Installation
entered into the "Administer" -> "Site Configuration" -> "Authorize.net
Webform" section.
As the last entry in the Webform, add a hidden field 'Transaction ID'.
Select 'Transaction ID' as the Authorize.net key to map to. The transaction
ID must be mapped, or the module will not work correctly.
Special fields:
* As the first field in the Webform, you must have a field for transaction
type. If you do not want your site visitors to see this field make it either
a hidden, or a value. Transaction type will allow people to choose between a
one-time transaction, or a subscription.
- One time transactions are straightforward and need no additional fields.
- Recurring subscriptions must also specify a 'length' and 'interval'. The
length and unit elements together define the interval in between payments.
If specified in terms of days, the interval can be between seven (7) and
365 days. If specified in terms of months, the interval can be between
one (1) and twelve (12) months.
- Interval (1 to 365)
- unit (days or months)
* As the last field in the Webform, add a hidden field 'Transaction ID'.
Select 'Transaction ID' as the Authorize.net key to map to. The transaction
ID must be mapped, or the module will not work correctly.
Save the webform.
...
...
authorizenetwebform.module
View file @
13176d7e
...
...
@@ -164,14 +164,17 @@ function authorizenetwebform_form_webform_client_form_alter(&$form, &$form_state
'data'
=>
$path
.
'/js/authorizenetwebform.js'
,
'type'
=>
'file'
);
$form
[
'#attached'
][
'js'
][]
=
array
(
'data'
=>
array
(
'authorizeNetWebform'
=>
$settings
),
'type'
=>
'setting'
);
$form
[
'#attached'
][
'js'
][]
=
array
(
'data'
=>
$js_url
,
'type'
=>
'external'
);
$form
[
'#attached'
][
'js'
][]
=
array
(
'data'
=>
array
(
'authorizeNetWebform'
=>
$settings
),
'type'
=>
'setting'
);
// Validate handler.
$form
[
'#validate'
][]
=
'authorizenetwebform_validate'
;
// Note: removing name attribute will prevent values from posting to the server.
...
...
@@ -180,6 +183,18 @@ function authorizenetwebform_form_webform_client_form_alter(&$form, &$form_state
array_unshift
(
$form
[
'#submit'
],
$first
,
'authorizenetwebform_submit'
);
}
/**
* Webform validation handler.
*
* @see authorizenetwebform_form_webform_client_form_alter().
*/
function
authorizenetwebform_validate
(
$form
,
&
$form_state
)
{
_authorizenetwebform_sanitize
(
$form_state
[
'values'
][
'submitted'
]);
dpm
(
'form values submitted'
);
dpm
(
$form_state
[
'values'
][
'submitted'
]);
}
/**
* Webform submit handler.
*
...
...
@@ -192,6 +207,7 @@ function authorizenetwebform_submit($form, &$form_state) {
}
$field_values
=
_authorizenetwebform_flatten_form_values
(
$form_state
[
'input'
][
'submitted'
]);
//dpm($field_values);
// Get key mappings for this webform.
$nid
=
$form_state
[
'values'
][
'details'
][
'nid'
];
// Nice shorthand.
...
...
@@ -199,6 +215,7 @@ function authorizenetwebform_submit($form, &$form_state) {
$field_map
=
variable_get
(
$variable_name
,
array
());
// We also want to access keys in the other direction.
$flipped_map
=
array_flip
(
$field_map
);
//dpm($flipped_map);
// Get the amount.
$amount_key
=
$flipped_map
[
'x_amount'
];
...
...
@@ -211,46 +228,109 @@ function authorizenetwebform_submit($form, &$form_state) {
$amount
=
((
double
)
$amount
)
*
((
double
)
$quantity
);
}
// Get the transaction nonce.
$transaction_key
=
$flipped_map
[
'x_trans_id'
];
// Get keys for the the transaction nonce, and required fields.
$trans_key
=
$flipped_map
[
'x_trans_id'
];
$type_key
=
$flipped_map
[
'x_trans_type'
];
$first_key
=
$flipped_map
[
'x_first_name'
];
$last_key
=
$flipped_map
[
'x_last_name'
];
// Establish data to send to AuthNet.
$data
=
array
(
'createTransactionRequest'
=>
array
(
'merchantAuthentication'
=>
array
(
'name'
=>
variable_get
(
'authorizenetwebform_login'
,
NULL
),
'transactionKey'
=>
variable_get
(
'authorizenetwebform_transaction'
,
NULL
),
),
'refId'
=>
$nid
.
'-'
.
time
(),
'transactionRequest'
=>
array
(
'transactionType'
=>
'authCaptureTransaction'
,
'amount'
=>
$amount
,
'payment'
=>
array
(
'opaqueData'
=>
array
(
'dataDescriptor'
=>
'COMMON.ACCEPT.INAPP.PAYMENT'
,
'dataValue'
=>
$field_values
[
$transaction_key
],
if
(
$field_values
[
$type_key
]
==
'one-time'
)
{
$top_key
=
'createTransactionRequest'
;
$data
=
array
(
'createTransactionRequest'
=>
array
(
'merchantAuthentication'
=>
array
(
'name'
=>
variable_get
(
'authorizenetwebform_login'
,
NULL
),
'transactionKey'
=>
variable_get
(
'authorizenetwebform_transaction'
,
NULL
),
),
'refId'
=>
$nid
.
'-'
.
time
(),
'transactionRequest'
=>
array
(
'transactionType'
=>
'authCaptureTransaction'
,
'amount'
=>
$amount
,
'payment'
=>
array
(
'opaqueData'
=>
array
(
'dataDescriptor'
=>
'COMMON.ACCEPT.INAPP.PAYMENT'
,
'dataValue'
=>
$field_values
[
$trans_key
],
),
),
'billTo'
=>
array
(
'firstName'
=>
$field_values
[
$first_key
],
'lastName'
=>
$field_values
[
$last_key
],
),
'customerIP'
=>
$_SERVER
[
'REMOTE_ADDR'
],
),
)
);
}
elseif
(
$field_values
[
$type_key
]
==
'subscription'
)
{
$top_key
=
'ARBCreateSubscriptionRequest'
;
$data
=
array
(
'ARBCreateSubscriptionRequest'
=>
array
(
'merchantAuthentication'
=>
array
(
'name'
=>
variable_get
(
'authorizenetwebform_login'
,
NULL
),
'transactionKey'
=>
variable_get
(
'authorizenetwebform_transaction'
,
NULL
),
),
'refId'
=>
$nid
.
'-'
.
time
(),
'subscription'
=>
array
(
'name'
=>
'Recurring donation'
,
'paymentSchedule'
=>
array
(
'interval'
=>
array
(
'length'
=>
1
,
'unit'
=>
'months'
,
),
'startDate'
=>
date
(
'Y-m-d'
),
'totalOccurrences'
=>
9999
,
'trialOccurrences'
=>
1
,
),
'amount'
=>
$amount
,
'trialAmount'
=>
'0.00'
,
'payment'
=>
array
(
'opaqueData'
=>
array
(
'dataDescriptor'
=>
'COMMON.ACCEPT.INAPP.PAYMENT'
,
'dataValue'
=>
$field_values
[
$trans_key
],
),
),
'billTo'
=>
array
(
'firstName'
=>
$field_values
[
$first_key
],
'lastName'
=>
$field_values
[
$last_key
],
),
),
'customerIP'
=>
$_SERVER
[
'REMOTE_ADDR'
],
),
)
);
)
;
}
if
(
FALSE
)
{
// @todo
// Optionally add the customer's billing data.
$data
[
'createTransactionRequest'
][
'billTo'
]
=
array
(
'firstName'
=>
''
,
'lastName'
=>
''
,
'address'
=>
''
,
'city'
=>
''
,
'state'
=>
''
,
'country'
=>
''
,
);
if
(
$field_values
[
$type_key
]
==
'one-time'
)
{
$second_key
=
'transactionRequest'
;
}
elseif
(
$field_values
[
$type_key
]
==
'subscription'
)
{
$second_key
=
'subscription'
;
}
$data
[
$top_key
][
$second_key
][
'billTo'
][
'company'
]
=
''
;
$data
[
$top_key
][
$second_key
][
'billTo'
][
'address'
]
=
''
;
$data
[
$top_key
][
$second_key
][
'billTo'
][
'city'
]
=
''
;
$data
[
$top_key
][
$second_key
][
'billTo'
][
'state'
]
=
''
;
$data
[
$top_key
][
$second_key
][
'billTo'
][
'country'
]
=
''
;
if
(
FALSE
)
{
// @todo
// Optionally add the customer's shipping data.
$data
[
$top_key
][
$second_key
][
'shipTo'
]
=
array
(
'firstName'
=>
''
,
'lastName'
=>
''
,
'company'
=>
''
,
'address'
=>
''
,
'city'
=>
''
,
'state'
=>
''
,
'country'
=>
''
,
);
}
}
if
(
FALSE
)
{
// @todo
// Optionally add additional custom fields.
$data
[
'createTransactionRequest'
][
'userFields'
]
=
array
(
$data
[
$top_key
][
'userFields'
]
=
array
(
'userField'
=>
array
(
'name'
=>
''
,
'value'
=>
''
,
...
...
@@ -281,40 +361,40 @@ function authorizenetwebform_submit($form, &$form_state) {
// Fix brokenness in the AuthNet JSON API response -- END.
$response_array
=
json_decode
(
trim
(
$post_response
),
TRUE
);
dpm
(
$response_array
);
//
dpm($response_array);
if
(
$response_array
[
'messages'
][
'resultCode'
]
==
'Ok'
)
{
drupal_set_message
(
'Your payment has been processed, thank you.'
);
}
else
{
drupal_set_message
(
'There was a problem with your payment. Please try again later.'
);
$code
=
$response_array
[
'messages'
][
'message'
][
'code'
];
$message
=
$response_array
[
'messages'
][
'message'
][
'text'
];
watchdog
(
'authorizenetwebform'
,
'Error @code from Authorize.net: @message'
,
array
(
'@code'
=>
$code
,
'@message'
=>
$message
));
drupal_set_message
(
t
(
'Your payment has been processed, thank you.'
));
}
elseif
(
$response_array
[
'messages'
][
'resultCode'
]
==
'Error'
)
{
foreach
(
$response_array
[
'messages'
][
'message'
]
as
$info
)
{
$code
=
$info
[
'code'
];
$text
=
$info
[
'text'
];
watchdog
(
'authorizenetwebform'
,
'Error @code from Authorize.net: @message'
,
array
(
'@code'
=>
$code
,
'@message'
=>
$text
));
// Sanitize form values. @todo
drupal_set_message
(
$code
.
': '
.
$text
,
'error'
);
form_set_error
(
NULL
,
$code
.
': '
.
$text
);
/*
$replacements = array();
// Blank out all but the last 4 CC #'s
$replacements[$cids[$flipped_map['x_card_num']]] = $anon_cc;
// Blank out the expiration date as well.
$replacements[$cids[$flipped_map['x_exp_date']]] = 'xxxxxx';
// Stop the submission.
$form_state
[
'rebuild'
]
=
TRUE
;
}
}
else
{
foreach
(
$response_array
[
'messages'
][
'message'
]
as
$info
)
{
$info
=
reset
();
$code
=
$info
[
'code'
];
$text
=
$info
[
'text'
];
watchdog
(
'authorizenetwebform'
,
'Error @code from Authorize.net: @message'
,
array
(
'@code'
=>
$code
,
'@message'
=>
$text
));
// Blank out the security code as well.
$replacements[$cids[$flipped_map['x_card_code']]] = 'xxx';
drupal_set_message
(
$code
.
': '
.
$text
,
'warning'
);
// Replace the old values with the new ones.
array_walk_recursive($form_values['submitted'], '_authorizenetwebform_replace_value_in_recursive', $replacements);
// Return our temporary values to the $form_state array
$form_state['values'] = $form_values;
*/
// Stop the submission.
$form_state
[
'rebuild'
]
=
TRUE
;
}
}
}
/**
...
...
@@ -456,6 +536,9 @@ function _authorizenetwebform_add_attributes(&$parent, &$attribute_map, $nid = F
// Update JS settings by adding the field mapping.
switch
(
$auth_net_key
)
{
// These first ones are required.
case
'x_trans_id'
:
$attribute_map
[
'transactionID'
]
=
'data-authnet-field--'
.
$lower_form_key
;
break
;
case
'x_card_num'
:
$attribute_map
[
'cardNumber'
]
=
'data-authnet-field--'
.
$lower_form_key
;
break
;
...
...
@@ -465,9 +548,13 @@ function _authorizenetwebform_add_attributes(&$parent, &$attribute_map, $nid = F
case
'x_exp_year'
:
$attribute_map
[
'year'
]
=
'data-authnet-field--'
.
$lower_form_key
;
break
;
case
'x_trans_id'
:
$attribute_map
[
'transactionID'
]
=
'data-authnet-field--'
.
$lower_form_key
;
case
'x_exp_date'
:
$attribute_map
[
$form_key
]
=
'data-authnet-field--'
.
$lower_form_key
;
// @todo need some special magic here to have different data
// attributes on month vs year selects for date field.
break
;
// The rest are optional.
case
'x_card_code'
:
$attribute_map
[
'cardCode'
]
=
'data-authnet-field--'
.
$lower_form_key
;
...
...
@@ -478,6 +565,7 @@ function _authorizenetwebform_add_attributes(&$parent, &$attribute_map, $nid = F
case
'x_full_name'
:
$attribute_map
[
'fullName'
]
=
'data-authnet-field--'
.
$lower_form_key
;
break
;
// Default to using the case-sensitive form key.
default
:
$attribute_map
[
$form_key
]
=
'data-authnet-field--'
.
$lower_form_key
;
...
...
@@ -490,3 +578,31 @@ function _authorizenetwebform_add_attributes(&$parent, &$attribute_map, $nid = F
return
$attribute_map
;
}
/**
* Replaces credit card details with x.
*
* @param array $element
* A structured data element, like a form array.
*/
function
_authorizenetwebform_sanitize
(
&
$element
)
{
$replace_me
=
array
(
'x_card_num'
,
'x_card_code'
,
'x_exp_month'
,
'x_exp_year'
);
foreach
(
$element
as
$key
=>
$value
)
{
if
(
is_array
(
$value
))
{
// Recurse.
_authorizenetwebform_sanitize
(
$value
);
}
elseif
(
in_array
(
$key
,
$replace_me
))
{
$length
=
strlen
(
$value
);
if
(
$length
<=
7
)
{
$element
[
$key
]
=
str_repeat
(
'x'
,
$length
);
}
else
{
$last_4
=
substr
(
$value
,
0
,
-
4
);
$new
=
str_repeat
(
'x'
,
$length
-
4
)
.
$last_4
;
$element
[
$key
]
=
$new
;
}
}
}
}
authorizenetwebform_fields.inc
View file @
13176d7e
...
...
@@ -16,25 +16,26 @@
*/
function
authorizenetwebform_available_fields
()
{
return
array
(
//
Special Field to block Processing
//
Special Field to block Processing.
0
=>
'--Do Not Map to an Authorize.Net field--'
,
// Transaction Info.
'x_trans_id'
=>
'Transaction ID (Required)'
,
'x_trans_type'
=>
'Transaction type (Required)'
,
'x_card_num'
=>
'Card Number (Required)'
,
'x_card_code'
=>
'Card Security Code (Required)'
,
'x_exp_date'
=>
'Expiration Date (Date field)'
,
'x_exp_month'
=>
'Expiration Month (2 Digits)'
,
// Needed for accept.js
'x_exp_year'
=>
'Expiration Year (2 Digits)'
,
// Needed for accept.js
'x_trans_id'
=>
'Transaction ID (Required)'
,
//'x_exp_date' => 'Expiration Date (Date component)',
'x_exp_month'
=>
'Expiration Month (2 Digits)'
,
'x_exp_year'
=>
'Expiration Year (2 Digits)'
,
'x_amount'
=>
'Amount (Required)'
,
//
//
Subscription info.
'anwf_quantity'
=>
'Quantity - Multiplies this number by Amount - 1 if not set'
,
'x_subscription'
=>
'Subscription'
,
// Cardholder Info.
'x_full_name'
=>
'Full Name'
,
// Needed for accept.js
'x_first_name'
=>
'First Name'
,
'x_last_name'
=>
'Last Name'
,
'x_first_name'
=>
'First Name (Required)'
,
'x_last_name'
=>
'Last Name (Required)'
,
'x_address'
=>
'Address'
,
'x_city'
=>
'City'
,
'x_state'
=>
'State'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment