@medalsocial/sdk 1.9.0 → 1.10.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/README.md +24 -1
- package/dist/openapi/medal-social.openapi.json +361 -0
- package/dist/src/index.d.mts +165 -1
- package/dist/src/index.d.ts +165 -1
- package/dist/src/index.js +59 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.mjs +59 -0
- package/dist/src/index.mjs.map +1 -1
- package/dist/src/openapi.generated.d.mts +237 -0
- package/dist/src/openapi.generated.d.ts +237 -0
- package/dist/src/openapi.generated.js.map +1 -1
- package/openapi/medal-social.openapi.yaml +267 -0
- package/package.json +1 -1
- package/skills/resources/SKILL.md +4 -0
|
@@ -988,6 +988,98 @@ paths:
|
|
|
988
988
|
$ref: "#/components/schemas/ApiResponse_BookingActionResult"
|
|
989
989
|
default:
|
|
990
990
|
$ref: "#/components/responses/ApiError"
|
|
991
|
+
/api/v1/bookings/{id}/payment:
|
|
992
|
+
parameters:
|
|
993
|
+
- $ref: "#/components/parameters/Id"
|
|
994
|
+
post:
|
|
995
|
+
tags: [Bookings]
|
|
996
|
+
operationId: startBookingPayment
|
|
997
|
+
summary: Start a Vipps payment for a booking
|
|
998
|
+
description: >-
|
|
999
|
+
Reserves (or charges) the booking's amount and returns the wallet
|
|
1000
|
+
redirect URL. The customer must have accepted your terms before this
|
|
1001
|
+
call — `terms_accepted` must be literally `true`, and a body omitting
|
|
1002
|
+
it is a 400. One live payment per booking: a second while one is
|
|
1003
|
+
outstanding answers 409, as does a booking that is not payable or a
|
|
1004
|
+
refusal from Vipps. A `return_url` this workspace's own sites do not
|
|
1005
|
+
vouch for answers 422, not 400 — the URL parses, it is just not yours.
|
|
1006
|
+
403 when the payments switch or the bookings module is off.
|
|
1007
|
+
requestBody:
|
|
1008
|
+
required: true
|
|
1009
|
+
content:
|
|
1010
|
+
application/json:
|
|
1011
|
+
schema:
|
|
1012
|
+
$ref: "#/components/schemas/StartBookingPaymentInput"
|
|
1013
|
+
responses:
|
|
1014
|
+
"200":
|
|
1015
|
+
description: >-
|
|
1016
|
+
The reference and the SHOW-ONCE redirect URL. The URL is never
|
|
1017
|
+
returned again — the payment behind it expires after ten minutes,
|
|
1018
|
+
so a cached one leads into a payment that no longer exists.
|
|
1019
|
+
content:
|
|
1020
|
+
application/json:
|
|
1021
|
+
schema:
|
|
1022
|
+
$ref: "#/components/schemas/ApiResponse_BookingPaymentStart"
|
|
1023
|
+
default:
|
|
1024
|
+
$ref: "#/components/responses/ApiError"
|
|
1025
|
+
get:
|
|
1026
|
+
tags: [Bookings]
|
|
1027
|
+
operationId: getBookingPayment
|
|
1028
|
+
summary: Read the newest payment attempt on a booking
|
|
1029
|
+
description: >-
|
|
1030
|
+
Returns the newest attempt only. A booking with no payment yet, an
|
|
1031
|
+
unknown booking id and another workspace's booking all answer 404
|
|
1032
|
+
alike, so this is not an existence oracle.
|
|
1033
|
+
responses:
|
|
1034
|
+
"200":
|
|
1035
|
+
description: The payment. `redirect_url` is deliberately absent here.
|
|
1036
|
+
content:
|
|
1037
|
+
application/json:
|
|
1038
|
+
schema:
|
|
1039
|
+
$ref: "#/components/schemas/ApiResponse_BookingPayment"
|
|
1040
|
+
default:
|
|
1041
|
+
$ref: "#/components/responses/ApiError"
|
|
1042
|
+
/api/v1/bookings/manage/{token}/payment:
|
|
1043
|
+
parameters:
|
|
1044
|
+
- $ref: "#/components/parameters/ManageToken"
|
|
1045
|
+
post:
|
|
1046
|
+
tags: [Bookings]
|
|
1047
|
+
operationId: startManageBookingPayment
|
|
1048
|
+
summary: Start a payment on the customer's behalf
|
|
1049
|
+
description: >-
|
|
1050
|
+
The manage-token twin of `startBookingPayment` — same body, same
|
|
1051
|
+
responses; only the credential that authorizes it differs.
|
|
1052
|
+
requestBody:
|
|
1053
|
+
required: true
|
|
1054
|
+
content:
|
|
1055
|
+
application/json:
|
|
1056
|
+
schema:
|
|
1057
|
+
$ref: "#/components/schemas/StartBookingPaymentInput"
|
|
1058
|
+
responses:
|
|
1059
|
+
"200":
|
|
1060
|
+
description: The reference and the show-once redirect URL.
|
|
1061
|
+
content:
|
|
1062
|
+
application/json:
|
|
1063
|
+
schema:
|
|
1064
|
+
$ref: "#/components/schemas/ApiResponse_BookingPaymentStart"
|
|
1065
|
+
default:
|
|
1066
|
+
$ref: "#/components/responses/ApiError"
|
|
1067
|
+
get:
|
|
1068
|
+
tags: [Bookings]
|
|
1069
|
+
operationId: getManageBookingPayment
|
|
1070
|
+
summary: Read the payment on the customer's own booking
|
|
1071
|
+
description: >-
|
|
1072
|
+
An unknown token, another workspace's token and a booking with no
|
|
1073
|
+
payment yet all answer 404 alike.
|
|
1074
|
+
responses:
|
|
1075
|
+
"200":
|
|
1076
|
+
description: The payment. `redirect_url` is deliberately absent here.
|
|
1077
|
+
content:
|
|
1078
|
+
application/json:
|
|
1079
|
+
schema:
|
|
1080
|
+
$ref: "#/components/schemas/ApiResponse_BookingPayment"
|
|
1081
|
+
default:
|
|
1082
|
+
$ref: "#/components/responses/ApiError"
|
|
991
1083
|
/api/v1/bookings/manage/{token}:
|
|
992
1084
|
parameters:
|
|
993
1085
|
- $ref: "#/components/parameters/ManageToken"
|
|
@@ -2785,6 +2877,19 @@ components:
|
|
|
2785
2877
|
BookingPaymentStatus:
|
|
2786
2878
|
type: string
|
|
2787
2879
|
enum: [none, reserved, captured, refunded]
|
|
2880
|
+
BookingPaymentMode:
|
|
2881
|
+
description: >-
|
|
2882
|
+
What a booking must have paid before the business honours it: nothing,
|
|
2883
|
+
a reservation captured later, or the full amount up front.
|
|
2884
|
+
type: string
|
|
2885
|
+
enum: [none, reserve, prepay]
|
|
2886
|
+
BookingPaymentState:
|
|
2887
|
+
description: >-
|
|
2888
|
+
The state of one payment attempt, in Medal's vocabulary rather than the
|
|
2889
|
+
wallet's — a Vipps payment stays AUTHORIZED after a capture, so read
|
|
2890
|
+
the øre aggregates to learn what actually moved.
|
|
2891
|
+
type: string
|
|
2892
|
+
enum: [created, authorized, captured, cancelled, refunded, failed, expired]
|
|
2788
2893
|
BookingCreatedVia:
|
|
2789
2894
|
type: string
|
|
2790
2895
|
enum: [web, dashboard, walk_in, api]
|
|
@@ -2811,6 +2916,7 @@ components:
|
|
|
2811
2916
|
- cancel_reason
|
|
2812
2917
|
- rescheduled_from_id
|
|
2813
2918
|
- payment_status
|
|
2919
|
+
- payment_mode
|
|
2814
2920
|
- amount_ore
|
|
2815
2921
|
- notes
|
|
2816
2922
|
- internal_notes
|
|
@@ -2862,6 +2968,12 @@ components:
|
|
|
2862
2968
|
type: [string, "null"]
|
|
2863
2969
|
payment_status:
|
|
2864
2970
|
$ref: "#/components/schemas/BookingPaymentStatus"
|
|
2971
|
+
payment_mode:
|
|
2972
|
+
description: >-
|
|
2973
|
+
What this booking required when it was made — frozen at creation.
|
|
2974
|
+
`payment_status: none` cannot tell "owes nothing" from "has not
|
|
2975
|
+
paid yet"; this can.
|
|
2976
|
+
$ref: "#/components/schemas/BookingPaymentMode"
|
|
2865
2977
|
amount_ore:
|
|
2866
2978
|
description: Price in integer øre. Never a float and never kroner.
|
|
2867
2979
|
type: [integer, "null"]
|
|
@@ -2895,6 +3007,7 @@ components:
|
|
|
2895
3007
|
- weekend_surcharge_pct
|
|
2896
3008
|
- resource_requirements
|
|
2897
3009
|
- bookable_online
|
|
3010
|
+
- payment
|
|
2898
3011
|
- max_per_booking
|
|
2899
3012
|
- color
|
|
2900
3013
|
- sort_order
|
|
@@ -2928,6 +3041,13 @@ components:
|
|
|
2928
3041
|
type: string
|
|
2929
3042
|
bookable_online:
|
|
2930
3043
|
type: boolean
|
|
3044
|
+
payment:
|
|
3045
|
+
description: >-
|
|
3046
|
+
Per-service payment requirement. `null` means no override — the
|
|
3047
|
+
workspace rule decides.
|
|
3048
|
+
oneOf:
|
|
3049
|
+
- $ref: "#/components/schemas/BookingPaymentMode"
|
|
3050
|
+
- type: "null"
|
|
2931
3051
|
max_per_booking:
|
|
2932
3052
|
type: [integer, "null"]
|
|
2933
3053
|
color:
|
|
@@ -3148,6 +3268,7 @@ components:
|
|
|
3148
3268
|
- party_sequence_id
|
|
3149
3269
|
- amount_ore
|
|
3150
3270
|
- payment_status
|
|
3271
|
+
- payment_mode
|
|
3151
3272
|
- time_zone
|
|
3152
3273
|
- cancel_window_hours
|
|
3153
3274
|
- reschedule_window_hours
|
|
@@ -3195,6 +3316,11 @@ components:
|
|
|
3195
3316
|
oneOf:
|
|
3196
3317
|
- $ref: "#/components/schemas/BookingPaymentStatus"
|
|
3197
3318
|
- type: "null"
|
|
3319
|
+
payment_mode:
|
|
3320
|
+
description: >-
|
|
3321
|
+
What this booking requires — what a manage page checks before
|
|
3322
|
+
offering «Betal nå».
|
|
3323
|
+
$ref: "#/components/schemas/BookingPaymentMode"
|
|
3198
3324
|
time_zone:
|
|
3199
3325
|
description: IANA zone the booking's local times should be rendered in.
|
|
3200
3326
|
type: [string, "null"]
|
|
@@ -3259,6 +3385,131 @@ components:
|
|
|
3259
3385
|
$ref: "#/components/schemas/BookingTimestampInput"
|
|
3260
3386
|
new_resource_id:
|
|
3261
3387
|
type: string
|
|
3388
|
+
StartBookingPaymentInput:
|
|
3389
|
+
description: >-
|
|
3390
|
+
Body for `startBookingPayment` and `startManageBookingPayment`.
|
|
3391
|
+
type: object
|
|
3392
|
+
required: [return_url, terms_accepted]
|
|
3393
|
+
properties:
|
|
3394
|
+
return_url:
|
|
3395
|
+
description: >-
|
|
3396
|
+
Where the wallet returns the customer. Must be a URL one of this
|
|
3397
|
+
workspace's own sites vouches for; anything else answers 422.
|
|
3398
|
+
type: string
|
|
3399
|
+
minLength: 1
|
|
3400
|
+
maxLength: 2048
|
|
3401
|
+
terms_accepted:
|
|
3402
|
+
description: >-
|
|
3403
|
+
Must be literally `true`. The customer has to actively accept the
|
|
3404
|
+
merchant's terms BEFORE a payment is initiated, so omitting it or
|
|
3405
|
+
sending `false` is a 400 and leaves no payment behind.
|
|
3406
|
+
const: true
|
|
3407
|
+
type: boolean
|
|
3408
|
+
terms_version:
|
|
3409
|
+
description: The caller's own version label for the terms that were accepted.
|
|
3410
|
+
type: string
|
|
3411
|
+
minLength: 1
|
|
3412
|
+
maxLength: 64
|
|
3413
|
+
terms_text:
|
|
3414
|
+
description: The exact text that was accepted, stored with the consent record.
|
|
3415
|
+
type: string
|
|
3416
|
+
maxLength: 2000
|
|
3417
|
+
BookingPaymentStart:
|
|
3418
|
+
description: >-
|
|
3419
|
+
The result of starting a payment. `redirect_url` is handed over here
|
|
3420
|
+
and nowhere else.
|
|
3421
|
+
type: object
|
|
3422
|
+
required: [reference, redirect_url, state]
|
|
3423
|
+
properties:
|
|
3424
|
+
reference:
|
|
3425
|
+
description: The wallet reference for this attempt.
|
|
3426
|
+
type: string
|
|
3427
|
+
redirect_url:
|
|
3428
|
+
description: >-
|
|
3429
|
+
Send the customer here UNCHANGED — hand it to the Vipps Widget SDK.
|
|
3430
|
+
SHOW-ONCE: it is not returned by `getBookingPayment`, and the
|
|
3431
|
+
payment behind it expires after ten minutes.
|
|
3432
|
+
type: string
|
|
3433
|
+
state:
|
|
3434
|
+
$ref: "#/components/schemas/BookingPaymentState"
|
|
3435
|
+
BookingPayment:
|
|
3436
|
+
description: >-
|
|
3437
|
+
One payment attempt on a booking. Money is integer øre, and the four
|
|
3438
|
+
aggregates are numbers rather than nulls — "nothing captured" is `0`.
|
|
3439
|
+
`redirect_url`, the wallet's own refusal text and the trace id are
|
|
3440
|
+
deliberately absent.
|
|
3441
|
+
type: object
|
|
3442
|
+
required:
|
|
3443
|
+
- reference
|
|
3444
|
+
- provider
|
|
3445
|
+
- state
|
|
3446
|
+
- mode
|
|
3447
|
+
- attempt
|
|
3448
|
+
- amount_ore
|
|
3449
|
+
- authorized_ore
|
|
3450
|
+
- captured_ore
|
|
3451
|
+
- refunded_ore
|
|
3452
|
+
- cancelled_ore
|
|
3453
|
+
- currency
|
|
3454
|
+
- capture_guaranteed_until
|
|
3455
|
+
- terms_version
|
|
3456
|
+
- terms_accepted_at
|
|
3457
|
+
- failure_code
|
|
3458
|
+
- created_at
|
|
3459
|
+
- updated_at
|
|
3460
|
+
properties:
|
|
3461
|
+
reference:
|
|
3462
|
+
type: string
|
|
3463
|
+
provider:
|
|
3464
|
+
const: vipps
|
|
3465
|
+
type: string
|
|
3466
|
+
state:
|
|
3467
|
+
$ref: "#/components/schemas/BookingPaymentState"
|
|
3468
|
+
mode:
|
|
3469
|
+
description: Never `none` — a payment exists only where one was required.
|
|
3470
|
+
type: string
|
|
3471
|
+
enum: [reserve, prepay]
|
|
3472
|
+
attempt:
|
|
3473
|
+
description: 1 for the first attempt on this booking, incrementing per retry.
|
|
3474
|
+
type: integer
|
|
3475
|
+
amount_ore:
|
|
3476
|
+
description: The amount this attempt is for, in integer øre.
|
|
3477
|
+
type: integer
|
|
3478
|
+
authorized_ore:
|
|
3479
|
+
type: integer
|
|
3480
|
+
captured_ore:
|
|
3481
|
+
type: integer
|
|
3482
|
+
refunded_ore:
|
|
3483
|
+
type: integer
|
|
3484
|
+
cancelled_ore:
|
|
3485
|
+
type: integer
|
|
3486
|
+
currency:
|
|
3487
|
+
const: NOK
|
|
3488
|
+
type: string
|
|
3489
|
+
capture_guaranteed_until:
|
|
3490
|
+
description: >-
|
|
3491
|
+
The last moment a capture is GUARANTEED to succeed. The card behind
|
|
3492
|
+
the wallet may release the reservation afterwards, so a capture
|
|
3493
|
+
past it can fail even though the payment still looks authorized.
|
|
3494
|
+
Null until the customer has approved.
|
|
3495
|
+
type: [string, "null"]
|
|
3496
|
+
format: date-time
|
|
3497
|
+
terms_version:
|
|
3498
|
+
type: [string, "null"]
|
|
3499
|
+
terms_accepted_at:
|
|
3500
|
+
type: [string, "null"]
|
|
3501
|
+
format: date-time
|
|
3502
|
+
failure_code:
|
|
3503
|
+
description: >-
|
|
3504
|
+
The wallet's numeric error code from the last failed operation —
|
|
3505
|
+
what a caller branches on.
|
|
3506
|
+
type: [string, "null"]
|
|
3507
|
+
created_at:
|
|
3508
|
+
type: [string, "null"]
|
|
3509
|
+
format: date-time
|
|
3510
|
+
updated_at:
|
|
3511
|
+
type: [string, "null"]
|
|
3512
|
+
format: date-time
|
|
3262
3513
|
BookingsPagination:
|
|
3263
3514
|
description: >-
|
|
3264
3515
|
Pagination for a bookings page. `truncated` is the extra statement:
|
|
@@ -3981,6 +4232,10 @@ components:
|
|
|
3981
4232
|
$ref: "#/components/schemas/Envelope_BookingActionResult"
|
|
3982
4233
|
ApiResponse_BookingRescheduleResult:
|
|
3983
4234
|
$ref: "#/components/schemas/Envelope_BookingRescheduleResult"
|
|
4235
|
+
ApiResponse_BookingPaymentStart:
|
|
4236
|
+
$ref: "#/components/schemas/Envelope_BookingPaymentStart"
|
|
4237
|
+
ApiResponse_BookingPayment:
|
|
4238
|
+
$ref: "#/components/schemas/Envelope_BookingPayment"
|
|
3984
4239
|
ApiResponse_ManageSummary:
|
|
3985
4240
|
$ref: "#/components/schemas/Envelope_ManageSummary"
|
|
3986
4241
|
ApiResponse_PortalLoginStartResult:
|
|
@@ -4318,6 +4573,18 @@ components:
|
|
|
4318
4573
|
properties:
|
|
4319
4574
|
data:
|
|
4320
4575
|
$ref: "#/components/schemas/BookingRescheduleResult"
|
|
4576
|
+
Envelope_BookingPaymentStart:
|
|
4577
|
+
type: object
|
|
4578
|
+
required: [data]
|
|
4579
|
+
properties:
|
|
4580
|
+
data:
|
|
4581
|
+
$ref: "#/components/schemas/BookingPaymentStart"
|
|
4582
|
+
Envelope_BookingPayment:
|
|
4583
|
+
type: object
|
|
4584
|
+
required: [data]
|
|
4585
|
+
properties:
|
|
4586
|
+
data:
|
|
4587
|
+
$ref: "#/components/schemas/BookingPayment"
|
|
4321
4588
|
Envelope_ManageSummary:
|
|
4322
4589
|
type: object
|
|
4323
4590
|
required: [data]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medalsocial/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "TypeScript SDK for Medal Social API — posts, emails, contacts, deals, helpdesk, webhooks, and GDPR compliance",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Medal Social / Ali Aljumaili",
|
|
@@ -38,6 +38,8 @@ Errors throw `MedalApiError` (see the `client` skill for details).
|
|
|
38
38
|
|---|---|---|
|
|
39
39
|
| `medal.bookings` | `src/resources/bookings.ts` | `listServices(opts?)`, `listResources()`, `availability(opts)`, `schedule(opts)`, `list(opts?)`, `create(input, opts?)`, `get(id)`, `update(id, input, opts?)`, `cancel(id, input?, opts?)`, `reschedule(id, input, opts?)`, `markNoShow(id, opts?)` — all **staff** semantics (policy windows bypassed) |
|
|
40
40
|
| `medal.bookings.manage` | `src/resources/bookings.ts` (`BookingsManage`) | `get(token)`, `cancel(token, input?, opts?)`, `reschedule(token, input, opts?)` — **customer** semantics (policy windows enforced) |
|
|
41
|
+
| `medal.bookings.payment` | `src/resources/bookings.ts` (`BookingsPayment`) | `start(id, input, opts?)`, `get(id)` — Vipps payment on a booking, as the business |
|
|
42
|
+
| `medal.bookings.manage.payment` | `src/resources/bookings.ts` (`BookingsManagePayment`) | `start(token, input, opts?)`, `get(token)` — the same two, on the customer's behalf |
|
|
41
43
|
| `medal.bookings.persons` | `src/resources/bookings.ts` (`BookingsPersons`) | `list(contactId, { include_inactive? })`, `create(input)` — persons a contact books for (children, pets, employees) |
|
|
42
44
|
| `medal.bookings.relations` | `src/resources/bookings.ts` (`BookingsRelations`) | `list(contactId)` → `{ outgoing, incoming }`, `create(input)` — directional relations between contacts |
|
|
43
45
|
| `medal.bookings.events` | `src/resources/bookings.ts` (`BookingsEvents`) | `list({ from, to, status? })`, `get(id)`, `create(input)` — arrangementer (scheduled group sessions); registering a booking to an event ships in a later release |
|
|
@@ -378,6 +380,8 @@ The `with { type: "json" }` import-attribute syntax requires Node 24+ or a bundl
|
|
|
378
380
|
| Hard-coded channel IDs in `posts.create` | Channels are workspace-specific | Call `posts.channels()` to discover them |
|
|
379
381
|
| Looping on `next_cursor` alone for pagination | Can be non-null when `has_more: false` | Loop on `pagination.has_more` |
|
|
380
382
|
| `medal.bookings.cancel(id)` to relay a customer's cancel | Bypasses the policy window and records `cancelled_by: 'staff'` | `medal.bookings.manage.cancel(token)` |
|
|
383
|
+
| Trusting the browser's return redirect after `payment.start` | The customer can close the tab or edit the URL; the outcome comes through Medal | Poll `medal.bookings.payment.get(id)`, or read `Booking.payment_status` |
|
|
384
|
+
| Caching `redirect_url` from `payment.start` | Show-once, and the payment expires in 10 minutes — a stale link leads nowhere | Start a new attempt |
|
|
381
385
|
| Dividing `amount_ore` / `price_ore` into kroner for storage | Integer øre; a float rounds and the invoice is wrong | Keep the integer; format only at the point of display |
|
|
382
386
|
| Reusing the old id or manage token after a reschedule | Reschedule inserts a NEW booking and mints a NEW token | Store `result.booking_id` and `result.manage_token` |
|
|
383
387
|
| Expecting `manage_token` on an idempotent replay | Tokens are redacted from replayed responses | Persist it from the first response — a replay cannot give it back |
|