ima-claude 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/cli.js +1064 -0
- package/package.json +49 -0
- package/platforms/claude/adapter.ts +115 -0
- package/platforms/junie/adapter.ts +254 -0
- package/platforms/junie/agents-template.md +113 -0
- package/platforms/junie/hook-translations.md +84 -0
- package/platforms/shared/detector.ts +27 -0
- package/platforms/shared/installer.ts +202 -0
- package/platforms/shared/types.ts +78 -0
- package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
- package/plugins/ima-claude/agents/explorer.md +30 -0
- package/plugins/ima-claude/agents/implementer.md +30 -0
- package/plugins/ima-claude/agents/memory.md +42 -0
- package/plugins/ima-claude/agents/reviewer.md +53 -0
- package/plugins/ima-claude/agents/tester.md +33 -0
- package/plugins/ima-claude/agents/wp-developer.md +46 -0
- package/plugins/ima-claude/hooks/README.md +145 -0
- package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
- package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
- package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
- package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
- package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
- package/plugins/ima-claude/hooks/docs_organization.py +104 -0
- package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
- package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
- package/plugins/ima-claude/hooks/hook_logger.py +69 -0
- package/plugins/ima-claude/hooks/hooks.json +239 -0
- package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
- package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
- package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
- package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
- package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
- package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
- package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
- package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
- package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
- package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
- package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
- package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
- package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
- package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
- package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
- package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
- package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
- package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
- package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
- package/plugins/ima-claude/personalities/README.md +45 -0
- package/plugins/ima-claude/personalities/enable-40k.md +69 -0
- package/plugins/ima-claude/personalities/enable-templars.md +69 -0
- package/plugins/ima-claude/skills/.research-summary.md +340 -0
- package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
- package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
- package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
- package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
- package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
- package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
- package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
- package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
- package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
- package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
- package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
- package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
- package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
- package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
- package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
- package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
- package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
- package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
- package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
- package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
- package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
- package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
- package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
- package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
- package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
- package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
- package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
- package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
- package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
- package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
- package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
- package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
- package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
- package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
- package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
- package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
- package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
- package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
- package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
- package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
- package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
- package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
- package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
- package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
- package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
- package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
- package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
- package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
- package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
- package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
- package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
- package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
- package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
- package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
- package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
- package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
- package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
- package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
- package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
- package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
- package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
- package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
- package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
- package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
- package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
- package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
- package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
- package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
- package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
- package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
- package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
- package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
- package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
- package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
- package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
- package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
- package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
- package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
- package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
- package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
- package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
- package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
- package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
- package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
- package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
- package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
- package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
- package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
- package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
- package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
- package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
- package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
- package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
- package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
- package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
- package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
- package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
- package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
# Authorize.Net PHP SDK — API Reference
|
|
2
|
+
|
|
3
|
+
Complete SDK class and method reference for `authorizenet/authorizenet` ^2.0.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [SDK Namespaces](#sdk-namespaces)
|
|
8
|
+
- [Payment Transactions](#payment-transactions)
|
|
9
|
+
- [Customer Profiles (CIM)](#customer-profiles-cim)
|
|
10
|
+
- [Recurring Billing (ARB)](#recurring-billing-arb)
|
|
11
|
+
- [Accept.js Token Handling](#acceptjs-token-handling)
|
|
12
|
+
- [Webhooks](#webhooks)
|
|
13
|
+
- [Transaction Reporting](#transaction-reporting)
|
|
14
|
+
- [Response Codes](#response-codes)
|
|
15
|
+
- [Field Constraints](#field-constraints)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## SDK Namespaces
|
|
20
|
+
|
|
21
|
+
```php
|
|
22
|
+
use net\authorize\api\contract\v1 as AnetAPI; // Data contracts
|
|
23
|
+
use net\authorize\api\controller as AnetController; // Request controllers
|
|
24
|
+
use net\authorize\api\constants\ANetEnvironment; // SANDBOX / PRODUCTION
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Payment Transactions
|
|
28
|
+
|
|
29
|
+
### CreateTransactionRequest
|
|
30
|
+
|
|
31
|
+
The universal transaction endpoint. Behavior varies by `transactionType`.
|
|
32
|
+
|
|
33
|
+
**Controller**: `AnetController\CreateTransactionController`
|
|
34
|
+
|
|
35
|
+
```php
|
|
36
|
+
$request = new AnetAPI\CreateTransactionRequest();
|
|
37
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
38
|
+
$request->setTransactionRequest($transaction_request);
|
|
39
|
+
|
|
40
|
+
$controller = new AnetController\CreateTransactionController($request);
|
|
41
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### TransactionRequestType — Key Setters
|
|
45
|
+
|
|
46
|
+
| Method | Type | Required | Notes |
|
|
47
|
+
|--------|------|----------|-------|
|
|
48
|
+
| `setTransactionType()` | string | Yes | See transaction types table |
|
|
49
|
+
| `setAmount()` | float | Yes | Decimal (e.g., 29.99) |
|
|
50
|
+
| `setPayment()` | PaymentType | Conditional | Required for new charges; not for profile charges |
|
|
51
|
+
| `setProfile()` | CustomerProfilePaymentType | Conditional | For charging stored profiles |
|
|
52
|
+
| `setRefTransId()` | string | Conditional | Required for refunds, voids, prior auth capture |
|
|
53
|
+
| `setBillTo()` | CustomerAddressType | No | Billing address |
|
|
54
|
+
| `setShipTo()` | CustomerAddressType | No | Shipping address |
|
|
55
|
+
| `setOrder()` | OrderType | No | Order description, invoice number |
|
|
56
|
+
| `setCustomer()` | CustomerDataType | No | Customer email, ID |
|
|
57
|
+
| `setLineItems()` | LineItemType[] | No | Array of line items |
|
|
58
|
+
| `setTax()` | ExtendedAmountType | No | Tax info |
|
|
59
|
+
| `setPoNumber()` | string | No | Purchase order number |
|
|
60
|
+
|
|
61
|
+
### Transaction Types
|
|
62
|
+
|
|
63
|
+
| Value | Description |
|
|
64
|
+
|-------|-------------|
|
|
65
|
+
| `authCaptureTransaction` | Authorize and capture in one step |
|
|
66
|
+
| `authOnlyTransaction` | Authorize only (capture later) |
|
|
67
|
+
| `priorAuthCaptureTransaction` | Capture a prior auth (requires `refTransId`) |
|
|
68
|
+
| `refundTransaction` | Refund settled transaction (requires `refTransId` + last 4 of card) |
|
|
69
|
+
| `voidTransaction` | Void unsettled transaction (requires `refTransId`) |
|
|
70
|
+
|
|
71
|
+
### Refund Requirements
|
|
72
|
+
|
|
73
|
+
Refunds require the original transaction ID AND payment info (last 4 digits):
|
|
74
|
+
|
|
75
|
+
```php
|
|
76
|
+
$credit_card = new AnetAPI\CreditCardType();
|
|
77
|
+
$credit_card->setCardNumber('XXXX1234'); // last 4 digits
|
|
78
|
+
$credit_card->setExpirationDate('XXXX'); // literal 'XXXX'
|
|
79
|
+
|
|
80
|
+
$payment = new AnetAPI\PaymentType();
|
|
81
|
+
$payment->setCreditCard($credit_card);
|
|
82
|
+
|
|
83
|
+
$tx = new AnetAPI\TransactionRequestType();
|
|
84
|
+
$tx->setTransactionType('refundTransaction');
|
|
85
|
+
$tx->setAmount($refund_amount);
|
|
86
|
+
$tx->setRefTransId($original_transaction_id);
|
|
87
|
+
$tx->setPayment($payment);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Refund constraints:
|
|
91
|
+
- Transaction must be settled (usually within 24h of capture)
|
|
92
|
+
- Refund amount ≤ original captured amount
|
|
93
|
+
- Partial refunds allowed (multiple refunds up to original amount)
|
|
94
|
+
- Default refund window: 180 days from settlement
|
|
95
|
+
|
|
96
|
+
### Void Requirements
|
|
97
|
+
|
|
98
|
+
Voids only work on **unsettled** transactions:
|
|
99
|
+
|
|
100
|
+
```php
|
|
101
|
+
$tx = new AnetAPI\TransactionRequestType();
|
|
102
|
+
$tx->setTransactionType('voidTransaction');
|
|
103
|
+
$tx->setRefTransId($transaction_id);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Response Parsing
|
|
107
|
+
|
|
108
|
+
```php
|
|
109
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
110
|
+
|
|
111
|
+
// Top-level result
|
|
112
|
+
$result_code = $response->getMessages()->getResultCode(); // 'Ok' or 'Error'
|
|
113
|
+
$messages = $response->getMessages()->getMessage(); // AnetAPI\MessagesType\MessageAType[]
|
|
114
|
+
$messages[0]->getCode(); // e.g., 'I00001'
|
|
115
|
+
$messages[0]->getText(); // e.g., 'Successful.'
|
|
116
|
+
|
|
117
|
+
// Transaction response (may be null)
|
|
118
|
+
$tresponse = $response->getTransactionResponse();
|
|
119
|
+
$tresponse->getTransId(); // Transaction ID
|
|
120
|
+
$tresponse->getAuthCode(); // Authorization code
|
|
121
|
+
$tresponse->getResponseCode(); // '1'=Approved, '2'=Declined, '3'=Error, '4'=Held
|
|
122
|
+
$tresponse->getAccountNumber(); // Masked card (e.g., 'XXXX1234')
|
|
123
|
+
$tresponse->getAccountType(); // 'Visa', 'Mastercard', etc.
|
|
124
|
+
|
|
125
|
+
// Transaction-level messages (success details)
|
|
126
|
+
$tresponse->getMessages(); // array of message objects (null if failed)
|
|
127
|
+
$tresponse->getMessages()[0]->getCode();
|
|
128
|
+
$tresponse->getMessages()[0]->getDescription();
|
|
129
|
+
|
|
130
|
+
// Transaction-level errors (decline/error details)
|
|
131
|
+
$tresponse->getErrors(); // array of error objects (null if success)
|
|
132
|
+
$tresponse->getErrors()[0]->getErrorCode();
|
|
133
|
+
$tresponse->getErrors()[0]->getErrorText();
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Response Code Values
|
|
137
|
+
|
|
138
|
+
| Code | Meaning |
|
|
139
|
+
|------|---------|
|
|
140
|
+
| `1` | Approved |
|
|
141
|
+
| `2` | Declined |
|
|
142
|
+
| `3` | Error |
|
|
143
|
+
| `4` | Held for review |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Customer Profiles (CIM)
|
|
148
|
+
|
|
149
|
+
CIM stores customer payment data securely on Authorize.Net's servers.
|
|
150
|
+
|
|
151
|
+
### Hierarchy
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
CustomerProfile
|
|
155
|
+
├── description, email, merchantCustomerId
|
|
156
|
+
├── PaymentProfile[] (credit cards, bank accounts)
|
|
157
|
+
│ ├── billTo (CustomerAddressType)
|
|
158
|
+
│ └── payment (PaymentType)
|
|
159
|
+
└── ShippingAddress[] (CustomerAddressType)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Create Customer Profile
|
|
163
|
+
|
|
164
|
+
**Controller**: `AnetController\CreateCustomerProfileController`
|
|
165
|
+
|
|
166
|
+
```php
|
|
167
|
+
$payment_profile = new AnetAPI\CustomerPaymentProfileType();
|
|
168
|
+
$payment_profile->setCustomerType('individual'); // or 'business'
|
|
169
|
+
$payment_profile->setBillTo($bill_to);
|
|
170
|
+
$payment_profile->setPayment($payment_type);
|
|
171
|
+
|
|
172
|
+
$customer_profile = new AnetAPI\CustomerProfileType();
|
|
173
|
+
$customer_profile->setDescription('Profile description');
|
|
174
|
+
$customer_profile->setEmail($email);
|
|
175
|
+
$customer_profile->setPaymentProfiles([$payment_profile]);
|
|
176
|
+
|
|
177
|
+
$request = new AnetAPI\CreateCustomerProfileRequest();
|
|
178
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
179
|
+
$request->setProfile($customer_profile);
|
|
180
|
+
$request->setValidationMode('liveMode'); // or 'testMode' for sandbox
|
|
181
|
+
|
|
182
|
+
$controller = new AnetController\CreateCustomerProfileController($request);
|
|
183
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
184
|
+
|
|
185
|
+
$customer_profile_id = $response->getCustomerProfileId();
|
|
186
|
+
$payment_profile_ids = $response->getCustomerPaymentProfileIdList(); // array
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Validation Modes
|
|
190
|
+
|
|
191
|
+
| Mode | Behavior |
|
|
192
|
+
|------|----------|
|
|
193
|
+
| `liveMode` | Runs $0.00 or $0.01 auth to validate card (production) |
|
|
194
|
+
| `testMode` | Validates format only, no auth (sandbox-safe) |
|
|
195
|
+
| `none` | No validation |
|
|
196
|
+
|
|
197
|
+
**Sandbox gotcha**: `liveMode` validation may fail with Accept.js opaque data in sandbox. Use `testMode` for sandbox environments.
|
|
198
|
+
|
|
199
|
+
### Create Customer Profile from Transaction
|
|
200
|
+
|
|
201
|
+
More reliable than direct creation, especially in sandbox:
|
|
202
|
+
|
|
203
|
+
```php
|
|
204
|
+
$request = new AnetAPI\CreateCustomerProfileFromTransactionRequest();
|
|
205
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
206
|
+
$request->setTransId($transaction_id);
|
|
207
|
+
|
|
208
|
+
// Optional: attach email
|
|
209
|
+
$customer = new AnetAPI\CustomerProfileBaseType();
|
|
210
|
+
$customer->setEmail($email);
|
|
211
|
+
$request->setCustomer($customer);
|
|
212
|
+
|
|
213
|
+
$controller = new AnetController\CreateCustomerProfileFromTransactionController($request);
|
|
214
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Add Payment Profile to Existing Customer
|
|
218
|
+
|
|
219
|
+
```php
|
|
220
|
+
$request = new AnetAPI\CreateCustomerPaymentProfileRequest();
|
|
221
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
222
|
+
$request->setCustomerProfileId($customer_profile_id);
|
|
223
|
+
$request->setPaymentProfile($payment_profile);
|
|
224
|
+
$request->setValidationMode($validation_mode);
|
|
225
|
+
|
|
226
|
+
$controller = new AnetController\CreateCustomerPaymentProfileController($request);
|
|
227
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
228
|
+
|
|
229
|
+
$new_payment_profile_id = $response->getCustomerPaymentProfileId();
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Get Customer Profile
|
|
233
|
+
|
|
234
|
+
```php
|
|
235
|
+
$request = new AnetAPI\GetCustomerProfileRequest();
|
|
236
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
237
|
+
$request->setCustomerProfileId($customer_profile_id);
|
|
238
|
+
|
|
239
|
+
$controller = new AnetController\GetCustomerProfileController($request);
|
|
240
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
241
|
+
|
|
242
|
+
$profile = $response->getProfile();
|
|
243
|
+
$payment_profiles = $profile->getPaymentProfiles(); // array
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Update Customer Payment Profile
|
|
247
|
+
|
|
248
|
+
```php
|
|
249
|
+
$request = new AnetAPI\UpdateCustomerPaymentProfileRequest();
|
|
250
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
251
|
+
$request->setCustomerProfileId($customer_profile_id);
|
|
252
|
+
$request->setPaymentProfile($updated_payment_profile);
|
|
253
|
+
|
|
254
|
+
$controller = new AnetController\UpdateCustomerPaymentProfileController($request);
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Delete Customer Profile
|
|
258
|
+
|
|
259
|
+
Deletes the profile AND all associated payment profiles and shipping addresses:
|
|
260
|
+
|
|
261
|
+
```php
|
|
262
|
+
$request = new AnetAPI\DeleteCustomerProfileRequest();
|
|
263
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
264
|
+
$request->setCustomerProfileId($customer_profile_id);
|
|
265
|
+
|
|
266
|
+
$controller = new AnetController\DeleteCustomerProfileController($request);
|
|
267
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Delete Payment Profile
|
|
271
|
+
|
|
272
|
+
```php
|
|
273
|
+
$request = new AnetAPI\DeleteCustomerPaymentProfileRequest();
|
|
274
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
275
|
+
$request->setCustomerProfileId($customer_profile_id);
|
|
276
|
+
$request->setCustomerPaymentProfileId($payment_profile_id);
|
|
277
|
+
|
|
278
|
+
$controller = new AnetController\DeleteCustomerPaymentProfileController($request);
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Charge Stored Profile
|
|
282
|
+
|
|
283
|
+
```php
|
|
284
|
+
$profile_to_charge = new AnetAPI\CustomerProfilePaymentType();
|
|
285
|
+
$profile_to_charge->setCustomerProfileId($customer_profile_id);
|
|
286
|
+
|
|
287
|
+
$payment_profile = new AnetAPI\PaymentProfileType();
|
|
288
|
+
$payment_profile->setPaymentProfileId($payment_profile_id);
|
|
289
|
+
$profile_to_charge->setPaymentProfile($payment_profile);
|
|
290
|
+
|
|
291
|
+
$tx = new AnetAPI\TransactionRequestType();
|
|
292
|
+
$tx->setTransactionType('authCaptureTransaction');
|
|
293
|
+
$tx->setAmount($amount);
|
|
294
|
+
$tx->setProfile($profile_to_charge);
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Recurring Billing (ARB)
|
|
300
|
+
|
|
301
|
+
### Create Subscription
|
|
302
|
+
|
|
303
|
+
**Controller**: `AnetController\ARBCreateSubscriptionController`
|
|
304
|
+
|
|
305
|
+
```php
|
|
306
|
+
$interval = new AnetAPI\PaymentScheduleType\IntervalAType();
|
|
307
|
+
$interval->setLength(1); // billing interval length
|
|
308
|
+
$interval->setUnit('months'); // 'months' or 'days'
|
|
309
|
+
|
|
310
|
+
$schedule = new AnetAPI\PaymentScheduleType();
|
|
311
|
+
$schedule->setInterval($interval);
|
|
312
|
+
$schedule->setStartDate(new \DateTime($start_date)); // Y-m-d
|
|
313
|
+
$schedule->setTotalOccurrences(9999); // 9999 = unlimited
|
|
314
|
+
|
|
315
|
+
// Optional trial period
|
|
316
|
+
$schedule->setTrialOccurrences(1);
|
|
317
|
+
|
|
318
|
+
// Using CIM profile (recommended)
|
|
319
|
+
$profile = new AnetAPI\CustomerProfileIdType();
|
|
320
|
+
$profile->setCustomerProfileId($customer_profile_id);
|
|
321
|
+
$profile->setCustomerPaymentProfileId($payment_profile_id);
|
|
322
|
+
|
|
323
|
+
$subscription = new AnetAPI\ARBSubscriptionType();
|
|
324
|
+
$subscription->setName('Monthly Membership'); // max 50 chars
|
|
325
|
+
$subscription->setPaymentSchedule($schedule);
|
|
326
|
+
$subscription->setAmount($amount);
|
|
327
|
+
$subscription->setProfile($profile);
|
|
328
|
+
$subscription->setTrialAmount(0.00); // if trial
|
|
329
|
+
|
|
330
|
+
$request = new AnetAPI\ARBCreateSubscriptionRequest();
|
|
331
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
332
|
+
$request->setSubscription($subscription);
|
|
333
|
+
|
|
334
|
+
$controller = new AnetController\ARBCreateSubscriptionController($request);
|
|
335
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
336
|
+
|
|
337
|
+
$subscription_id = $response->getSubscriptionId();
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Interval Constraints
|
|
341
|
+
|
|
342
|
+
| Unit | Min Length | Max Length |
|
|
343
|
+
|------|-----------|-----------|
|
|
344
|
+
| `days` | 7 | 365 |
|
|
345
|
+
| `months` | 1 | 12 |
|
|
346
|
+
|
|
347
|
+
### Cancel Subscription
|
|
348
|
+
|
|
349
|
+
```php
|
|
350
|
+
$request = new AnetAPI\ARBCancelSubscriptionRequest();
|
|
351
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
352
|
+
$request->setSubscriptionId($subscription_id);
|
|
353
|
+
|
|
354
|
+
$controller = new AnetController\ARBCancelSubscriptionController($request);
|
|
355
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Get Subscription Status
|
|
359
|
+
|
|
360
|
+
```php
|
|
361
|
+
$request = new AnetAPI\ARBGetSubscriptionStatusRequest();
|
|
362
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
363
|
+
$request->setSubscriptionId($subscription_id);
|
|
364
|
+
|
|
365
|
+
$controller = new AnetController\ARBGetSubscriptionStatusController($request);
|
|
366
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
367
|
+
|
|
368
|
+
$status = $response->getStatus(); // active, expired, suspended, canceled, terminated
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Subscription Statuses
|
|
372
|
+
|
|
373
|
+
| Status | Meaning |
|
|
374
|
+
|--------|---------|
|
|
375
|
+
| `active` | Billing normally |
|
|
376
|
+
| `expired` | All occurrences completed |
|
|
377
|
+
| `suspended` | Payment failed (auto-retry pending) |
|
|
378
|
+
| `canceled` | Merchant canceled via API or UI |
|
|
379
|
+
| `terminated` | System terminated (too many failures) |
|
|
380
|
+
|
|
381
|
+
### Update Subscription
|
|
382
|
+
|
|
383
|
+
Once created, you CANNOT change: start date, interval length/unit, trial period. Create a new subscription for those changes.
|
|
384
|
+
|
|
385
|
+
You CAN update: amount, payment profile, name, billing address.
|
|
386
|
+
|
|
387
|
+
```php
|
|
388
|
+
$subscription = new AnetAPI\ARBSubscriptionType();
|
|
389
|
+
$subscription->setAmount($new_amount);
|
|
390
|
+
|
|
391
|
+
$request = new AnetAPI\ARBUpdateSubscriptionRequest();
|
|
392
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
393
|
+
$request->setSubscriptionId($subscription_id);
|
|
394
|
+
$request->setSubscription($subscription);
|
|
395
|
+
|
|
396
|
+
$controller = new AnetController\ARBUpdateSubscriptionController($request);
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Accept.js Token Handling
|
|
402
|
+
|
|
403
|
+
Accept.js sends card data directly to Authorize.Net from the browser, returning a one-time payment nonce.
|
|
404
|
+
|
|
405
|
+
### Payment Nonce → OpaqueDataType
|
|
406
|
+
|
|
407
|
+
```php
|
|
408
|
+
$opaque_data = new AnetAPI\OpaqueDataType();
|
|
409
|
+
$opaque_data->setDataDescriptor('COMMON.ACCEPT.INAPP.PAYMENT');
|
|
410
|
+
$opaque_data->setDataValue($nonce_from_acceptjs);
|
|
411
|
+
|
|
412
|
+
$payment = new AnetAPI\PaymentType();
|
|
413
|
+
$payment->setOpaqueData($opaque_data);
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Token Lifecycle
|
|
417
|
+
|
|
418
|
+
- Valid for **15 minutes** after creation
|
|
419
|
+
- Single-use — consumed on first API call
|
|
420
|
+
- Contains no readable card data (opaque)
|
|
421
|
+
|
|
422
|
+
### Accept.js vs Accept Hosted vs Accept.UI
|
|
423
|
+
|
|
424
|
+
| Method | PCI Level | Control | Description |
|
|
425
|
+
|--------|-----------|---------|-------------|
|
|
426
|
+
| Accept.js (custom form) | SAQ A-EP | Full | Your form, JS tokenizes before submit |
|
|
427
|
+
| Accept.js (hosted form) | SAQ A | Medium | Authorize.Net renders fields in modal |
|
|
428
|
+
| Accept Hosted | SAQ A | Low | Full redirect/iframe to Authorize.Net page |
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## Webhooks
|
|
433
|
+
|
|
434
|
+
### Event Types
|
|
435
|
+
|
|
436
|
+
**Payment events** (triggered by transactions):
|
|
437
|
+
|
|
438
|
+
| Event | Description |
|
|
439
|
+
|-------|-------------|
|
|
440
|
+
| `net.authorize.payment.authcapture.created` | Auth+capture completed |
|
|
441
|
+
| `net.authorize.payment.authorization.created` | Auth-only completed |
|
|
442
|
+
| `net.authorize.payment.capture.created` | Prior auth captured |
|
|
443
|
+
| `net.authorize.payment.refund.created` | Refund processed |
|
|
444
|
+
| `net.authorize.payment.void.created` | Transaction voided |
|
|
445
|
+
| `net.authorize.payment.priorAuthCapture.created` | Prior auth captured |
|
|
446
|
+
|
|
447
|
+
**Subscription events**:
|
|
448
|
+
|
|
449
|
+
| Event | Description |
|
|
450
|
+
|-------|-------------|
|
|
451
|
+
| `net.authorize.customer.subscription.created` | Subscription created |
|
|
452
|
+
| `net.authorize.customer.subscription.updated` | Subscription modified |
|
|
453
|
+
| `net.authorize.customer.subscription.suspended` | Payment failed |
|
|
454
|
+
| `net.authorize.customer.subscription.terminated` | System terminated |
|
|
455
|
+
| `net.authorize.customer.subscription.cancelled` | Merchant cancelled |
|
|
456
|
+
| `net.authorize.customer.subscription.expiring` | Approaching end date |
|
|
457
|
+
|
|
458
|
+
**Customer profile events**:
|
|
459
|
+
|
|
460
|
+
| Event | Description |
|
|
461
|
+
|-------|-------------|
|
|
462
|
+
| `net.authorize.customer.created` | Customer profile created |
|
|
463
|
+
| `net.authorize.customer.updated` | Customer profile updated |
|
|
464
|
+
| `net.authorize.customer.deleted` | Customer profile deleted |
|
|
465
|
+
| `net.authorize.customer.paymentProfile.created` | Payment profile added |
|
|
466
|
+
| `net.authorize.customer.paymentProfile.updated` | Payment profile updated |
|
|
467
|
+
| `net.authorize.customer.paymentProfile.deleted` | Payment profile deleted |
|
|
468
|
+
|
|
469
|
+
**Fraud events**:
|
|
470
|
+
|
|
471
|
+
| Event | Description |
|
|
472
|
+
|-------|-------------|
|
|
473
|
+
| `net.authorize.payment.fraud.approved` | Held transaction approved |
|
|
474
|
+
| `net.authorize.payment.fraud.declined` | Held transaction declined |
|
|
475
|
+
| `net.authorize.payment.fraud.held` | Transaction held for review |
|
|
476
|
+
|
|
477
|
+
### Subscription Billing: Which Event Fires?
|
|
478
|
+
|
|
479
|
+
When a subscription charges the next billing cycle, it fires a **payment event** (`net.authorize.payment.authcapture.created`), NOT a subscription event. Subscription events only fire for lifecycle changes (create, cancel, suspend, terminate).
|
|
480
|
+
|
|
481
|
+
### HMAC-SHA512 Signature Validation
|
|
482
|
+
|
|
483
|
+
Authorize.Net signs webhook payloads with the Signature Key using HMAC-SHA512. The signature is in the `X-ANET-Signature` header as `sha512=<HEXDIGEST>`.
|
|
484
|
+
|
|
485
|
+
```php
|
|
486
|
+
function validate_webhook_signature(
|
|
487
|
+
string $raw_body,
|
|
488
|
+
?string $signature_header,
|
|
489
|
+
string $signature_key
|
|
490
|
+
): bool {
|
|
491
|
+
if (empty($raw_body) || empty($signature_header) || empty($signature_key)) {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
$prefix = 'sha512=';
|
|
496
|
+
if (stripos($signature_header, $prefix) !== 0) {
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
$received = strtoupper(substr($signature_header, strlen($prefix)));
|
|
501
|
+
$computed = strtoupper(hash_hmac('sha512', $raw_body, $signature_key));
|
|
502
|
+
|
|
503
|
+
return hash_equals($computed, $received);
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### Webhook Payload Structure
|
|
508
|
+
|
|
509
|
+
```json
|
|
510
|
+
{
|
|
511
|
+
"notificationId": "unique-notification-id",
|
|
512
|
+
"eventType": "net.authorize.payment.authcapture.created",
|
|
513
|
+
"eventDate": "2025-01-15T12:00:00Z",
|
|
514
|
+
"webhookId": "webhook-config-id",
|
|
515
|
+
"payload": {
|
|
516
|
+
"responseCode": 1,
|
|
517
|
+
"authCode": "ABC123",
|
|
518
|
+
"avsResponse": "Y",
|
|
519
|
+
"authAmount": 29.99,
|
|
520
|
+
"entityName": "transaction",
|
|
521
|
+
"id": "123456789"
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Idempotency
|
|
527
|
+
|
|
528
|
+
Authorize.Net may deliver webhooks multiple times. Use `notificationId` for deduplication:
|
|
529
|
+
|
|
530
|
+
```php
|
|
531
|
+
$idempotency_key = 'ima_wh_' . md5($notification_id);
|
|
532
|
+
if (get_transient($idempotency_key)) {
|
|
533
|
+
return; // already processed
|
|
534
|
+
}
|
|
535
|
+
set_transient($idempotency_key, true, 3 * DAY_IN_SECONDS);
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## Transaction Reporting
|
|
541
|
+
|
|
542
|
+
### Get Transaction Details
|
|
543
|
+
|
|
544
|
+
```php
|
|
545
|
+
$request = new AnetAPI\GetTransactionDetailsRequest();
|
|
546
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
547
|
+
$request->setTransId($transaction_id);
|
|
548
|
+
|
|
549
|
+
$controller = new AnetController\GetTransactionDetailsController($request);
|
|
550
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
551
|
+
|
|
552
|
+
$tx = $response->getTransaction();
|
|
553
|
+
$tx->getTransId();
|
|
554
|
+
$tx->getTransactionStatus(); // settledSuccessfully, authorizedPendingCapture, etc.
|
|
555
|
+
$tx->getSettleAmount();
|
|
556
|
+
$tx->getSubmitTimeUTC();
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Get Merchant Details (Connection Test)
|
|
560
|
+
|
|
561
|
+
```php
|
|
562
|
+
$request = new AnetAPI\GetMerchantDetailsRequest();
|
|
563
|
+
$request->setMerchantAuthentication($merchant_auth);
|
|
564
|
+
|
|
565
|
+
$controller = new AnetController\GetMerchantDetailsController($request);
|
|
566
|
+
$response = $controller->executeWithApiResponse($api_url);
|
|
567
|
+
// result_code 'Ok' = credentials valid
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## Response Codes
|
|
573
|
+
|
|
574
|
+
### API-Level Result Codes
|
|
575
|
+
|
|
576
|
+
| Result | Meaning |
|
|
577
|
+
|--------|---------|
|
|
578
|
+
| `Ok` | Request processed (check transaction-level for actual result) |
|
|
579
|
+
| `Error` | API-level failure (auth, format, etc.) |
|
|
580
|
+
|
|
581
|
+
### Common Error Codes
|
|
582
|
+
|
|
583
|
+
| Code | Description | Recovery |
|
|
584
|
+
|------|-------------|----------|
|
|
585
|
+
| `E00001` | Internal error | Retry after delay |
|
|
586
|
+
| `E00003` | Invalid credentials | Verify api_login_id and transaction_key |
|
|
587
|
+
| `E00007` | Permission denied | Check account permissions |
|
|
588
|
+
| `E00012` | Duplicate subscription | Check existing subscriptions |
|
|
589
|
+
| `E00027` | Transaction declined | User should try different payment method |
|
|
590
|
+
| `E00039` | Duplicate record | Extract existing ID from error text with regex `/ID\s+(\d+)/` |
|
|
591
|
+
| `E00040` | Record not found | Profile was deleted or ID is wrong |
|
|
592
|
+
| `E00042` | Max payment profiles reached | Delete an old profile first (max 10 per customer) |
|
|
593
|
+
| `E00043` | Max shipping addresses reached | Delete an old address first |
|
|
594
|
+
|
|
595
|
+
### Transaction Response Codes
|
|
596
|
+
|
|
597
|
+
| Code | Meaning | Action |
|
|
598
|
+
|------|---------|--------|
|
|
599
|
+
| `1` | Approved | Process success |
|
|
600
|
+
| `2` | Declined | Show decline message to user |
|
|
601
|
+
| `3` | Error | Log and show generic error |
|
|
602
|
+
| `4` | Held for review | Wait for webhook notification |
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## Field Constraints
|
|
607
|
+
|
|
608
|
+
| Field | Max Length | Notes |
|
|
609
|
+
|-------|-----------|-------|
|
|
610
|
+
| Subscription name | 50 chars | Truncate, don't reject |
|
|
611
|
+
| Order description | 255 chars | Truncate, don't reject |
|
|
612
|
+
| Invoice number | 20 chars | Alphanumeric |
|
|
613
|
+
| First/Last name | 50 chars each | |
|
|
614
|
+
| Company | 50 chars | |
|
|
615
|
+
| Address | 60 chars | |
|
|
616
|
+
| City | 40 chars | |
|
|
617
|
+
| State | 40 chars | |
|
|
618
|
+
| Zip | 20 chars | |
|
|
619
|
+
| Country | 60 chars | |
|
|
620
|
+
| Phone | 25 chars | |
|
|
621
|
+
| Email | 255 chars | |
|
|
622
|
+
| Customer ID | 20 chars | merchantCustomerId |
|
|
623
|
+
| Payment profiles per customer | 10 max | Error E00042 if exceeded |
|
|
624
|
+
| Shipping addresses per customer | 100 max | |
|