@monimesl/dot-cli 0.1.0-alpha.35 → 0.1.0-alpha.37
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/templates/showcase/dot.ts +1 -0
- package/dist/templates/showcase/pages/dash/payments/controller.ts +82 -0
- package/dist/templates/showcase/pages/dash/payments/state.ts +10 -0
- package/dist/templates/showcase/pages/dash/payments/view.dml +38 -0
- package/dist/templates/showcase/pages/index/state.ts +6 -0
- package/package.json +6 -6
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { PaymentMethod, PaymentResult } from '@monimesl/dot-runtime';
|
|
2
|
+
import { errorMessage, isDashError } from '@monimesl/dot-runtime';
|
|
3
|
+
|
|
4
|
+
import state from './state';
|
|
5
|
+
|
|
6
|
+
// SLE 75.00 a ticket, in minor units as Monime counts money.
|
|
7
|
+
const TICKET_PRICE = 7500;
|
|
8
|
+
|
|
9
|
+
export default definePage({
|
|
10
|
+
initialState: state,
|
|
11
|
+
configs: { navigationBar: { title: 'Payments' } },
|
|
12
|
+
mutations: {
|
|
13
|
+
setTickets: (_state, event: ValueEvent) => ({ tickets: Number(event.detail.value) }),
|
|
14
|
+
},
|
|
15
|
+
actions: {
|
|
16
|
+
// data-provider limits the payment to one mobile money provider, such as m17 for Orange Money.
|
|
17
|
+
async pay(state, event: DataEvent<{ provider?: string }>) {
|
|
18
|
+
// A new reference for each order, as the same reference never pays twice.
|
|
19
|
+
const reference = `tickets-${Date.now().toString(36)}`;
|
|
20
|
+
this.setState({ reference, note: '' });
|
|
21
|
+
let methods: PaymentMethod[] | undefined;
|
|
22
|
+
if (event.data.provider) {
|
|
23
|
+
methods = [{ type: 'momo', providers: { include: [event.data.provider] } }];
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const result = await this.dash.payments.request({
|
|
27
|
+
order: {
|
|
28
|
+
name: 'Jazz Night tickets',
|
|
29
|
+
reference,
|
|
30
|
+
description: 'Saturday 8 pm at the Bo Town Hall',
|
|
31
|
+
lineItems: [
|
|
32
|
+
{
|
|
33
|
+
name: 'Standing ticket',
|
|
34
|
+
unitPrice: { currency: 'SLE', value: TICKET_PRICE },
|
|
35
|
+
quantity: state.tickets,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
metadata: { show: 'jazz-night' },
|
|
39
|
+
},
|
|
40
|
+
methods,
|
|
41
|
+
});
|
|
42
|
+
this.setState(shownResult(result));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (isDashError(error, 'cancelled')) {
|
|
45
|
+
this.setState({ note: 'You closed the payment without paying.' });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.setState({ note: errorMessage(error) });
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
async checkPayment(state) {
|
|
52
|
+
try {
|
|
53
|
+
const result = await this.dash.payments.get(state.reference);
|
|
54
|
+
if (result === undefined) {
|
|
55
|
+
this.setState({ note: 'There is no payment for this order yet.' });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.setState(shownResult(result));
|
|
59
|
+
} catch (error) {
|
|
60
|
+
this.setState({ note: errorMessage(error) });
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// The Monime resource behind the payment differs by method.
|
|
67
|
+
function shownResult(result: PaymentResult) {
|
|
68
|
+
let resource = result.paymentId ?? '';
|
|
69
|
+
if (result.method === 'card') {
|
|
70
|
+
resource = result.checkoutSessionId;
|
|
71
|
+
} else if (result.method === 'momo') {
|
|
72
|
+
resource = result.paymentCodeId;
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
method: result.method,
|
|
76
|
+
status: result.status,
|
|
77
|
+
amount: `${result.amount.currency} ${(result.amount.value / 100).toFixed(2)}`,
|
|
78
|
+
resource,
|
|
79
|
+
orderNumber: result.orderNumber ?? '',
|
|
80
|
+
note: '',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<View>
|
|
2
|
+
<Text variant="title">dash.payments</Text>
|
|
3
|
+
<Text>Takes a payment for an order through Dash's own payment sheet. The person picks a linked account, a card or mobile money, and the money goes to the Space that owns the dot. It needs the payments permission in dot.json.</Text>
|
|
4
|
+
|
|
5
|
+
<View gap="small">
|
|
6
|
+
<Text variant="subtitle">request</Text>
|
|
7
|
+
<Text variant="caption" tone="muted">The dot sends the order: its name, its own reference, and the line items. Dash adds up the total and shows it. With methods, the dot chooses which ways to pay to offer, in order, such as only Orange Money.</Text>
|
|
8
|
+
<View variant="card" gap="medium">
|
|
9
|
+
<Stepper label="Tickets" min="1" max="10" hint="SLE 75.00 each" value="{{ tickets }}" onChange="setTickets" />
|
|
10
|
+
<Button onClick="pay">Pay any way</Button>
|
|
11
|
+
<Button variant="secondary" data-provider="m17" onClick="pay">Pay with Orange Money only</Button>
|
|
12
|
+
</View>
|
|
13
|
+
</View>
|
|
14
|
+
|
|
15
|
+
<View gap="small">
|
|
16
|
+
<Text variant="subtitle">get</Text>
|
|
17
|
+
<Text variant="caption" tone="muted">Reads a payment back by the order's reference, such as one still pending, or after the dot opens again. The ID is the Monime resource behind the payment: a checkout session for a card, a payment code for mobile money, or the payment itself for a linked account.</Text>
|
|
18
|
+
<View variant="card" gap="medium">
|
|
19
|
+
<If condition="{{ status }}">
|
|
20
|
+
<View gap="none">
|
|
21
|
+
<DetailRow label="reference" value="{{ reference }}" />
|
|
22
|
+
<DetailRow label="method" value="{{ method }}" />
|
|
23
|
+
<DetailRow label="status" value="{{ status }}" />
|
|
24
|
+
<DetailRow label="amount" value="{{ amount }}" />
|
|
25
|
+
<DetailRow label="resource" value="{{ resource }}" />
|
|
26
|
+
<If condition="{{ orderNumber }}">
|
|
27
|
+
<DetailRow label="orderNumber" value="{{ orderNumber }}" />
|
|
28
|
+
</If>
|
|
29
|
+
</View>
|
|
30
|
+
</If>
|
|
31
|
+
<Button variant="secondary" onClick="checkPayment" disabled="{{ !reference }}">Check the payment</Button>
|
|
32
|
+
</View>
|
|
33
|
+
</View>
|
|
34
|
+
|
|
35
|
+
<If condition="{{ note }}">
|
|
36
|
+
<Notice tone="danger">{{ note }}</Notice>
|
|
37
|
+
</If>
|
|
38
|
+
</View>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monimesl/dot-cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.37",
|
|
4
4
|
"description": "The dotctl command: build mini apps and run them in the simulator",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"typescript": "^5.9.3",
|
|
26
26
|
"uqr": "^0.1.3",
|
|
27
|
-
"@monimesl/dot-compiler": "0.1.0-alpha.
|
|
28
|
-
"@monimesl/dot-core": "0.1.0-alpha.
|
|
29
|
-
"@monimesl/dot-dml-parser": "0.1.0-alpha.
|
|
30
|
-
"@monimesl/dot-script-parser": "0.1.0-alpha.
|
|
31
|
-
"@monimesl/dot-simulator": "0.1.0-alpha.
|
|
27
|
+
"@monimesl/dot-compiler": "0.1.0-alpha.37",
|
|
28
|
+
"@monimesl/dot-core": "0.1.0-alpha.37",
|
|
29
|
+
"@monimesl/dot-dml-parser": "0.1.0-alpha.37",
|
|
30
|
+
"@monimesl/dot-script-parser": "0.1.0-alpha.37",
|
|
31
|
+
"@monimesl/dot-simulator": "0.1.0-alpha.37"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^22.20.4",
|