@sails-pay/bachs 0.0.5 → 0.0.6

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.
@@ -65,6 +65,7 @@ function buildProductCart(items) {
65
65
  function buildCheckoutSessionPayload(inputs, adapterConfig = {}) {
66
66
  const productCollectionId =
67
67
  inputs.productCollectionId || inputs.productCollection
68
+ const productCart = buildProductCart(inputs.items)
68
69
  const checkoutData = inputs.checkoutData || {}
69
70
  const returnUrl =
70
71
  inputs.returnUrl ||
@@ -74,8 +75,13 @@ function buildCheckoutSessionPayload(inputs, adapterConfig = {}) {
74
75
 
75
76
  return withoutUndefined({
76
77
  customer: buildCustomerPayload(inputs),
77
- product_cart: buildProductCart(inputs.items),
78
+ product_cart: productCart,
78
79
  product_collection_id: productCollectionId,
80
+ // A session prices itself with products or with a raw amount, never both.
81
+ pricing:
82
+ productCart || productCollectionId
83
+ ? undefined
84
+ : buildPricingPayload(inputs),
79
85
  billing_currency: inputs.billingCurrency,
80
86
  allowed_payment_method_types: inputs.allowedPaymentMethodTypes,
81
87
  return_url: returnUrl,
@@ -20,7 +20,7 @@ function validateCheckoutConnect(connect, { isCheckoutSession }) {
20
20
  if (!isCheckoutSession) {
21
21
  return invalid(
22
22
  'connect',
23
- 'is only supported on product checkout sessions (items or productCollectionId).'
23
+ 'is only supported on checkout sessions (items, productCollectionId, or pricing).'
24
24
  )
25
25
  }
26
26
 
@@ -147,9 +147,18 @@ module.exports = require('machine').build({
147
147
  const hasProductCollection = Boolean(
148
148
  inputs.productCollectionId || inputs.productCollection
149
149
  )
150
- const shouldUseCheckoutSession = hasItems || hasProductCollection
150
+ const hasPricing = Boolean(
151
+ inputs.pricing || inputs.amount !== undefined || inputs.currency
152
+ )
153
+ // A split belongs to the platform, and Bachs only splits checkout
154
+ // sessions. A session takes products or a raw price, so a checkout that
155
+ // states its own amount and currency can be split too.
156
+ const shouldUseCheckoutSession =
157
+ hasItems ||
158
+ hasProductCollection ||
159
+ (hasPricing && inputs.connect !== undefined)
151
160
 
152
- if (shouldUseCheckoutSession && hasItems === hasProductCollection) {
161
+ if (hasItems && hasProductCollection) {
153
162
  return exits.invalidRequest({
154
163
  message:
155
164
  'Provide exactly one of items or productCollectionId for a Bachs checkout session.'
@@ -179,7 +188,11 @@ module.exports = require('machine').build({
179
188
  ? buildCheckoutSessionPayload(inputs, adapterConfig)
180
189
  : buildPureCheckoutPayload(inputs, adapterConfig)
181
190
 
182
- if (!shouldUseCheckoutSession && !payload.pricing) {
191
+ if (
192
+ !payload.product_cart &&
193
+ !payload.product_collection_id &&
194
+ !payload.pricing
195
+ ) {
183
196
  return exits.invalidRequest({
184
197
  message:
185
198
  'Provide product items/productCollectionId or pure checkout pricing.'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sails-pay/bachs",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Bachs adapter for Sails Pay",
5
5
  "main": "adapter.js",
6
6
  "scripts": {
@@ -405,6 +405,70 @@ test('checkout splits a checkout session with a connected account', async () =>
405
405
  assert.equal(body.connect, undefined)
406
406
  })
407
407
 
408
+ test('checkout splits a product-less checkout session', async () => {
409
+ const calls = []
410
+
411
+ fetch.setFetchImplementation(async (url, options) => {
412
+ calls.push({ url, options })
413
+
414
+ return {
415
+ ok: true,
416
+ status: 201,
417
+ statusText: 'Created',
418
+ text: async () =>
419
+ JSON.stringify({ checkout_url: 'https://pay.bachs.io/c/raw-split' })
420
+ }
421
+ })
422
+
423
+ const checkoutUrl = await checkout({
424
+ apiKey: 'sk_sandbox_123',
425
+ amount: '10500.00',
426
+ currency: 'NGN',
427
+ billingCurrency: 'NGN',
428
+ customer: { email: 'sponsor@example.com' },
429
+ reference: 'sponsorship_2',
430
+ connect: { destination: 'acct_123', platformFee: '500.00' }
431
+ })
432
+
433
+ assert.equal(checkoutUrl, 'https://pay.bachs.io/c/raw-split')
434
+ assert.equal(
435
+ calls[0].url,
436
+ 'https://sandbox-api.bachs.io/v1/checkout-sessions'
437
+ )
438
+
439
+ const body = JSON.parse(calls[0].options.body)
440
+ assert.deepEqual(body.pricing, { currency: 'NGN', amount: '10500.00' })
441
+ assert.deepEqual(body.transfer_data, { destination: 'acct_123' })
442
+ assert.equal(body.platform_fee, '500.00')
443
+ assert.equal(body.billing_currency, 'NGN')
444
+ assert.equal('product_cart' in body, false)
445
+ })
446
+
447
+ test('a pure checkout without connect still posts to /checkouts', async () => {
448
+ const calls = []
449
+
450
+ fetch.setFetchImplementation(async (url, options) => {
451
+ calls.push({ url, options })
452
+
453
+ return {
454
+ ok: true,
455
+ status: 201,
456
+ statusText: 'Created',
457
+ text: async () =>
458
+ JSON.stringify({ checkout_url: 'https://pay.bachs.io/c/raw' })
459
+ }
460
+ })
461
+
462
+ await checkout({
463
+ apiKey: 'sk_sandbox_123',
464
+ amount: '10500.00',
465
+ currency: 'NGN',
466
+ customer: { email: 'sponsor@example.com' }
467
+ })
468
+
469
+ assert.equal(calls[0].url, 'https://sandbox-api.bachs.io/v1/checkouts')
470
+ })
471
+
408
472
  test('checkout without connect sends no split fields', async () => {
409
473
  const calls = []
410
474
 
@@ -437,16 +501,6 @@ const invalidConnectCases = [
437
501
  field: 'connect',
438
502
  message: /must be an object/
439
503
  },
440
- {
441
- name: 'connect on a pure checkout',
442
- inputs: {
443
- amount: '10500.00',
444
- currency: 'NGN',
445
- connect: { destination: 'acct_123', platformFee: '500.00' }
446
- },
447
- field: 'connect',
448
- message: /only supported on product checkout sessions/
449
- },
450
504
  {
451
505
  name: 'connect without a destination',
452
506
  inputs: {