arispay 0.1.1 → 0.1.3
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/dist/cli.js +63 -24
- package/package.json +1 -1
- package/src/cli.ts +57 -23
package/dist/cli.js
CHANGED
|
@@ -122,12 +122,13 @@ ${bold("Connect your agent to ArisPay")}`);
|
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
124
|
console.log(`
|
|
125
|
-
${dim("How does your agent make payments?")}
|
|
126
|
-
console.log(` ${dim(" platform \u2014 Your app triggers payments on behalf of the agent (default)")}`);
|
|
127
|
-
console.log(` ${dim(" autonomous \u2014 The agent decides when to pay, within spend limits you set")}
|
|
125
|
+
${dim("How does your agent make payments?")}
|
|
128
126
|
`);
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
console.log(` ${cyan("[1]")} Platform ${dim("\u2014 Your app triggers payments on behalf of the agent")}`);
|
|
128
|
+
console.log(` ${cyan("[2]")} Autonomous ${dim("\u2014 The agent decides when to pay, within spend limits you set")}
|
|
129
|
+
`);
|
|
130
|
+
const modeChoice = await prompt(` Enter choice ${dim("[1]")}: `);
|
|
131
|
+
const mode = modeChoice === "2" ? "autonomous" : "platform";
|
|
131
132
|
console.log(`
|
|
132
133
|
${dim("Connecting agent...")}`);
|
|
133
134
|
try {
|
|
@@ -138,13 +139,14 @@ ${bold("Connect your agent to ArisPay")}`);
|
|
|
138
139
|
});
|
|
139
140
|
const a = agent;
|
|
140
141
|
const config = loadConfig(BRAND);
|
|
141
|
-
saveConfig(BRAND, { ...config, agentId: a.id });
|
|
142
|
+
saveConfig(BRAND, { ...config, agentId: a.id, agentName: a.name || name });
|
|
142
143
|
console.log();
|
|
143
144
|
success(`Agent connected!
|
|
144
145
|
`);
|
|
145
|
-
console.log(` ${dim("ArisPay
|
|
146
|
-
console.log(` ${dim("
|
|
147
|
-
console.log(` ${dim("
|
|
146
|
+
console.log(` ${dim("ArisPay has created a Visa TAP cryptographic identity for your agent.")}`);
|
|
147
|
+
console.log(` ${dim("Every payment your agent makes is signed with this identity so merchants")}`);
|
|
148
|
+
console.log(` ${dim("can verify it is authorised. A circuit breaker is also in place to")}`);
|
|
149
|
+
console.log(` ${dim("auto-pause your agent if unusual spending is detected.")}
|
|
148
150
|
`);
|
|
149
151
|
console.log(` ${bold("Agent ID:")} ${a.id}`);
|
|
150
152
|
console.log(` ${bold("Name:")} ${a.name}`);
|
|
@@ -188,26 +190,52 @@ ${bold("Add a payment method")}`);
|
|
|
188
190
|
const methodChoice = await prompt(` Enter choice: `);
|
|
189
191
|
if (methodChoice === "1") {
|
|
190
192
|
console.log(`
|
|
191
|
-
${dim("
|
|
193
|
+
${dim("Enter your card details below. They are sent directly to Fiserv for")}`);
|
|
194
|
+
console.log(` ${dim("tokenization \u2014 ArisPay never sees or stores your full card number.")}
|
|
195
|
+
`);
|
|
196
|
+
const cardNumber = await promptSecret(` Card number: `);
|
|
197
|
+
if (!cardNumber) {
|
|
198
|
+
console.log(dim(" Cancelled."));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const expiry = await prompt(` Expiry ${dim("(MM/YY)")}: `);
|
|
202
|
+
if (!expiry) {
|
|
203
|
+
console.log(dim(" Cancelled."));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const securityCode = await promptSecret(` CVV: `);
|
|
207
|
+
if (!securityCode) {
|
|
208
|
+
console.log(dim(" Cancelled."));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const [expiryMonth, expiryYear] = expiry.split("/").map((s) => s.trim());
|
|
212
|
+
if (!expiryMonth || !expiryYear) {
|
|
213
|
+
console.log(` ${dim("Invalid expiry format. Use MM/YY.")}`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
console.log(`
|
|
217
|
+
${dim("Tokenizing card...")}`);
|
|
192
218
|
try {
|
|
193
219
|
const result = await client.users.addPaymentMethod({
|
|
194
220
|
userId,
|
|
195
221
|
type: "card",
|
|
196
|
-
|
|
222
|
+
cardNumber: cardNumber.replace(/\s/g, ""),
|
|
223
|
+
expiryMonth,
|
|
224
|
+
expiryYear: expiryYear.length === 2 ? `20${expiryYear}` : expiryYear,
|
|
225
|
+
securityCode
|
|
197
226
|
});
|
|
198
227
|
const r = result;
|
|
199
228
|
console.log();
|
|
200
|
-
success(`Card
|
|
201
|
-
`);
|
|
202
|
-
console.log(` ${bold("Open this URL to securely enter your card details:")}
|
|
203
|
-
`);
|
|
204
|
-
console.log(` ${cyan(r.setupUrl)}
|
|
229
|
+
success(`Card tokenized!
|
|
205
230
|
`);
|
|
206
|
-
console.log(` ${
|
|
231
|
+
console.log(` ${bold("Card:")} ${r.cardBrand?.toUpperCase() || "Card"} ending in ${r.cardLast4 || "****"}`);
|
|
232
|
+
console.log(` ${bold("Token:")} ${dim(r.tokenId || "stored securely")}`);
|
|
233
|
+
console.log(`
|
|
234
|
+
${dim("Your card is now linked to your agent. You can make test payments.")}
|
|
207
235
|
`);
|
|
208
236
|
} catch (e) {
|
|
209
237
|
console.log();
|
|
210
|
-
console.error(` \x1B[31m\u2717\x1B[0m ${e.message || "Failed to
|
|
238
|
+
console.error(` \x1B[31m\u2717\x1B[0m ${e.message || "Failed to tokenize card"}`);
|
|
211
239
|
}
|
|
212
240
|
} else if (methodChoice === "2") {
|
|
213
241
|
console.log();
|
|
@@ -256,9 +284,11 @@ ${bold("Make a test payment")}`);
|
|
|
256
284
|
`);
|
|
257
285
|
const config = loadConfig(BRAND);
|
|
258
286
|
const storedAgentId = config.agentId;
|
|
287
|
+
const storedAgentName = config.agentName;
|
|
259
288
|
let agentId;
|
|
260
289
|
if (storedAgentId) {
|
|
261
|
-
const
|
|
290
|
+
const agentLabel = storedAgentName ? bold(storedAgentName) : dim(storedAgentId.slice(0, 12) + "...");
|
|
291
|
+
const useStored = await prompt(` Use agent ${agentLabel}? ${dim("(Y/n)")}: `);
|
|
262
292
|
if (useStored.toLowerCase() === "n") {
|
|
263
293
|
agentId = await prompt(` Agent ID: `);
|
|
264
294
|
if (!agentId) {
|
|
@@ -275,25 +305,34 @@ ${bold("Make a test payment")}`);
|
|
|
275
305
|
return;
|
|
276
306
|
}
|
|
277
307
|
}
|
|
278
|
-
const amountStr = await prompt(` Amount
|
|
279
|
-
const
|
|
280
|
-
if (!
|
|
308
|
+
const amountStr = await prompt(` Amount ${dim("(e.g. 5.00)")}: $`);
|
|
309
|
+
const dollars = parseFloat(amountStr);
|
|
310
|
+
if (!dollars || isNaN(dollars)) {
|
|
281
311
|
console.log(dim(" Invalid amount. Cancelled."));
|
|
282
312
|
return;
|
|
283
313
|
}
|
|
284
|
-
const
|
|
314
|
+
const amount = Math.round(dollars * 100);
|
|
315
|
+
const memo = await prompt(` Description ${dim("(appears on the transaction record)")}: `);
|
|
285
316
|
if (!memo) {
|
|
286
317
|
console.log(dim(" Cancelled."));
|
|
287
318
|
return;
|
|
288
319
|
}
|
|
320
|
+
const userId = config.endUserId;
|
|
321
|
+
if (!userId) {
|
|
322
|
+
console.log(`
|
|
323
|
+
${dim("No payment method set up yet. Run option [2] first.")}`);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
289
326
|
console.log(`
|
|
290
|
-
${dim(`Sending $${
|
|
327
|
+
${dim(`Sending $${dollars.toFixed(2)} test payment...`)}`);
|
|
291
328
|
try {
|
|
292
329
|
const payment = await client.payments.create({
|
|
293
330
|
agentId,
|
|
331
|
+
userId,
|
|
294
332
|
amount,
|
|
295
333
|
currency: "USD",
|
|
296
334
|
memo,
|
|
335
|
+
merchantUrl: "https://test.arispay.app",
|
|
297
336
|
idempotencyKey: `cli_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
|
|
298
337
|
});
|
|
299
338
|
const p = payment;
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -140,12 +140,12 @@ async function wizardConnectAgent(client: ArisPayClient): Promise<void> {
|
|
|
140
140
|
const name = await prompt(` What is your agent called? `);
|
|
141
141
|
if (!name) { console.log(dim(' Cancelled.')); return; }
|
|
142
142
|
|
|
143
|
-
console.log(`\n ${dim('How does your agent make payments?')}`);
|
|
144
|
-
console.log(` ${dim('
|
|
145
|
-
console.log(` ${dim('
|
|
143
|
+
console.log(`\n ${dim('How does your agent make payments?')}\n`);
|
|
144
|
+
console.log(` ${cyan('[1]')} Platform ${dim('— Your app triggers payments on behalf of the agent')}`);
|
|
145
|
+
console.log(` ${cyan('[2]')} Autonomous ${dim('— The agent decides when to pay, within spend limits you set')}\n`);
|
|
146
146
|
|
|
147
|
-
const
|
|
148
|
-
const mode =
|
|
147
|
+
const modeChoice = await prompt(` Enter choice ${dim('[1]')}: `);
|
|
148
|
+
const mode = modeChoice === '2' ? 'autonomous' : 'platform';
|
|
149
149
|
|
|
150
150
|
console.log(`\n ${dim('Connecting agent...')}`);
|
|
151
151
|
|
|
@@ -159,13 +159,14 @@ async function wizardConnectAgent(client: ArisPayClient): Promise<void> {
|
|
|
159
159
|
|
|
160
160
|
// Store agent ID so other steps can auto-fill it
|
|
161
161
|
const config = loadConfig(BRAND);
|
|
162
|
-
saveConfig(BRAND, { ...config, agentId: a.id } as any);
|
|
162
|
+
saveConfig(BRAND, { ...config, agentId: a.id, agentName: a.name || name } as any);
|
|
163
163
|
|
|
164
164
|
console.log();
|
|
165
165
|
success(`Agent connected!\n`);
|
|
166
|
-
console.log(` ${dim('ArisPay
|
|
167
|
-
console.log(` ${dim('
|
|
168
|
-
console.log(` ${dim('
|
|
166
|
+
console.log(` ${dim('ArisPay has created a Visa TAP cryptographic identity for your agent.')}`);
|
|
167
|
+
console.log(` ${dim('Every payment your agent makes is signed with this identity so merchants')}`);
|
|
168
|
+
console.log(` ${dim('can verify it is authorised. A circuit breaker is also in place to')}`);
|
|
169
|
+
console.log(` ${dim('auto-pause your agent if unusual spending is detected.')}\n`);
|
|
169
170
|
console.log(` ${bold('Agent ID:')} ${a.id}`);
|
|
170
171
|
console.log(` ${bold('Name:')} ${a.name}`);
|
|
171
172
|
console.log(` ${bold('Mode:')} ${a.mode || mode}`);
|
|
@@ -210,22 +211,43 @@ async function wizardAddPaymentMethod(client: ArisPayClient): Promise<void> {
|
|
|
210
211
|
const methodChoice = await prompt(` Enter choice: `);
|
|
211
212
|
|
|
212
213
|
if (methodChoice === '1') {
|
|
213
|
-
console.log(`\n ${dim('
|
|
214
|
+
console.log(`\n ${dim('Enter your card details below. They are sent directly to Fiserv for')}`);
|
|
215
|
+
console.log(` ${dim('tokenization — ArisPay never sees or stores your full card number.')}\n`);
|
|
216
|
+
|
|
217
|
+
const cardNumber = await promptSecret(` Card number: `);
|
|
218
|
+
if (!cardNumber) { console.log(dim(' Cancelled.')); return; }
|
|
219
|
+
|
|
220
|
+
const expiry = await prompt(` Expiry ${dim('(MM/YY)')}: `);
|
|
221
|
+
if (!expiry) { console.log(dim(' Cancelled.')); return; }
|
|
222
|
+
|
|
223
|
+
const securityCode = await promptSecret(` CVV: `);
|
|
224
|
+
if (!securityCode) { console.log(dim(' Cancelled.')); return; }
|
|
225
|
+
|
|
226
|
+
const [expiryMonth, expiryYear] = expiry.split('/').map(s => s.trim());
|
|
227
|
+
if (!expiryMonth || !expiryYear) {
|
|
228
|
+
console.log(` ${dim('Invalid expiry format. Use MM/YY.')}`);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
console.log(`\n ${dim('Tokenizing card...')}`);
|
|
214
233
|
try {
|
|
215
234
|
const result = await client.users.addPaymentMethod({
|
|
216
235
|
userId,
|
|
217
236
|
type: 'card',
|
|
218
|
-
|
|
237
|
+
cardNumber: cardNumber.replace(/\s/g, ''),
|
|
238
|
+
expiryMonth,
|
|
239
|
+
expiryYear: expiryYear.length === 2 ? `20${expiryYear}` : expiryYear,
|
|
240
|
+
securityCode,
|
|
219
241
|
});
|
|
220
242
|
const r = result as any;
|
|
221
243
|
console.log();
|
|
222
|
-
success(`Card
|
|
223
|
-
console.log(` ${bold('
|
|
224
|
-
console.log(`
|
|
225
|
-
console.log(
|
|
244
|
+
success(`Card tokenized!\n`);
|
|
245
|
+
console.log(` ${bold('Card:')} ${r.cardBrand?.toUpperCase() || 'Card'} ending in ${r.cardLast4 || '****'}`);
|
|
246
|
+
console.log(` ${bold('Token:')} ${dim(r.tokenId || 'stored securely')}`);
|
|
247
|
+
console.log(`\n ${dim('Your card is now linked to your agent. You can make test payments.')}\n`);
|
|
226
248
|
} catch (e: any) {
|
|
227
249
|
console.log();
|
|
228
|
-
console.error(` \x1b[31m✗\x1b[0m ${e.message || 'Failed to
|
|
250
|
+
console.error(` \x1b[31m✗\x1b[0m ${e.message || 'Failed to tokenize card'}`);
|
|
229
251
|
}
|
|
230
252
|
} else if (methodChoice === '2') {
|
|
231
253
|
console.log();
|
|
@@ -262,14 +284,17 @@ async function wizardAddPaymentMethod(client: ArisPayClient): Promise<void> {
|
|
|
262
284
|
|
|
263
285
|
async function wizardTestPayment(client: ArisPayClient): Promise<void> {
|
|
264
286
|
console.log(`\n${bold('Make a test payment')}`);
|
|
265
|
-
console.log(` ${dim('Verify your integration works by sending a test payment.')}
|
|
287
|
+
console.log(` ${dim('Verify your integration works by sending a test payment.')}`);
|
|
288
|
+
console.log(` ${dim('This is a sandbox test — no real funds are moved.')}\n`);
|
|
266
289
|
|
|
267
290
|
const config = loadConfig(BRAND);
|
|
268
291
|
const storedAgentId = (config as any).agentId;
|
|
292
|
+
const storedAgentName = (config as any).agentName;
|
|
269
293
|
|
|
270
294
|
let agentId: string;
|
|
271
295
|
if (storedAgentId) {
|
|
272
|
-
const
|
|
296
|
+
const agentLabel = storedAgentName ? bold(storedAgentName) : dim(storedAgentId.slice(0, 12) + '...');
|
|
297
|
+
const useStored = await prompt(` Use agent ${agentLabel}? ${dim('(Y/n)')}: `);
|
|
273
298
|
if (useStored.toLowerCase() === 'n') {
|
|
274
299
|
agentId = await prompt(` Agent ID: `);
|
|
275
300
|
if (!agentId) { console.log(dim(' Cancelled.')); return; }
|
|
@@ -281,21 +306,30 @@ async function wizardTestPayment(client: ArisPayClient): Promise<void> {
|
|
|
281
306
|
if (!agentId) { console.log(dim(' Cancelled.')); return; }
|
|
282
307
|
}
|
|
283
308
|
|
|
284
|
-
const amountStr = await prompt(` Amount
|
|
285
|
-
const
|
|
286
|
-
if (!
|
|
309
|
+
const amountStr = await prompt(` Amount ${dim('(e.g. 5.00)')}: $`);
|
|
310
|
+
const dollars = parseFloat(amountStr);
|
|
311
|
+
if (!dollars || isNaN(dollars)) { console.log(dim(' Invalid amount. Cancelled.')); return; }
|
|
312
|
+
const amount = Math.round(dollars * 100);
|
|
287
313
|
|
|
288
|
-
const memo = await prompt(`
|
|
314
|
+
const memo = await prompt(` Description ${dim('(appears on the transaction record)')}: `);
|
|
289
315
|
if (!memo) { console.log(dim(' Cancelled.')); return; }
|
|
290
316
|
|
|
291
|
-
|
|
317
|
+
const userId = (config as any).endUserId;
|
|
318
|
+
if (!userId) {
|
|
319
|
+
console.log(`\n ${dim('No payment method set up yet. Run option [2] first.')}`);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
console.log(`\n ${dim(`Sending $${dollars.toFixed(2)} test payment...`)}`);
|
|
292
324
|
|
|
293
325
|
try {
|
|
294
326
|
const payment = await client.payments.create({
|
|
295
327
|
agentId,
|
|
328
|
+
userId,
|
|
296
329
|
amount,
|
|
297
330
|
currency: 'USD',
|
|
298
331
|
memo,
|
|
332
|
+
merchantUrl: 'https://test.arispay.app',
|
|
299
333
|
idempotencyKey: `cli_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
300
334
|
} as any);
|
|
301
335
|
const p = payment as any;
|