vue-klasha 0.0.4 → 1.0.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 +216 -113
- package/dist/klasha.esm.js +503 -0
- package/dist/klasha.esm.js.map +1 -0
- package/dist/klasha.min.js +2 -1
- package/dist/klasha.min.js.map +1 -0
- package/package.json +58 -30
- package/src/index.d.ts +64 -0
- package/src/index.js +18 -0
- package/src/klasha.vue +191 -130
- package/src/load-script.js +100 -0
- package/src/klasha-options.ts +0 -109
package/README.md
CHANGED
|
@@ -1,191 +1,294 @@
|
|
|
1
|
-
#
|
|
1
|
+
# vue-klasha
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Klasha payment gateway component for **Vue 2.x**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/vue-klasha)
|
|
6
|
+
[](LICENSE)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
---
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
## ⚠️ Upgrade immediately if you are on 0.0.x
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
**Every 0.0.x release of `vue-klasha` (up to and including 0.0.5) is completely
|
|
13
|
+
non-functional.** Do not ship it.
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
| What was broken | Detail |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **The script it loaded no longer exists** | 0.0.x fetched `https://klastatic.fra1.digitaloceanspaces.com/{test,prod}/js/klasha-integration.js`. That bucket has been **deleted** and returns `NoSuchBucket` (404) for both test and prod. `window.KlashaClient` is therefore never defined, and clicking Pay does nothing. |
|
|
18
|
+
| **The 9th `isTestMode` argument is missing** | `KlashaClient` takes `isTestMode` as its 9th constructor argument, and on the current `pay.js` it is the *only* thing selecting sandbox vs production. 0.0.x passes **8**. This matters now: the current script uses one URL for both environments, so repointing without adding the argument would route sandbox traffic to production. (While the old CDN existed, 0.0.x did pick `/test/js/` vs `/prod/js/` correctly, so there is no reason to think past sandbox payments went live.) |
|
|
19
|
+
| **Your `txRef` was thrown away** | The kit was built with `tx_ref: this.txFef || this.makeId(16)`. There is no `txFef` prop — it is a typo for `txRef` — so *every* transaction got a random reference instead of yours. Reconciliation was impossible. |
|
|
20
|
+
| **The phone number never reached Klasha** | The kit set `phone_number`; the gateway reads `phone`. |
|
|
21
|
+
| **Your merchant key was logged to the console** | `console.log(klashaOptions)` printed the whole options object, `merchantKey` included, on every payment. |
|
|
22
|
+
| **Duplicate DOM ids** | A `<div id="ktest">` was appended to `<body>` on every mount and never removed. |
|
|
23
|
+
| **jQuery was loaded for nothing** | Two scripts were injected; the gateway does not use jQuery. |
|
|
24
|
+
|
|
25
|
+
**1.0.0 fixes all of the above.**
|
|
26
|
+
|
|
27
|
+
## Vue 2 only
|
|
28
|
+
|
|
29
|
+
This package targets **Vue 2.6 / 2.7**. Vue is a `peerDependency`, so your app's
|
|
30
|
+
Vue is the one that gets used (0.0.x listed Vue as a regular `dependency`, which
|
|
31
|
+
could give you two Vue instances).
|
|
32
|
+
|
|
33
|
+
**Using Vue 3?** Use [`vue3-klasha`](https://www.npmjs.com/package/vue3-klasha)
|
|
34
|
+
instead.
|
|
35
|
+
|
|
36
|
+
> Note: Vue 2 reached end-of-life in December 2023 and no longer receives
|
|
37
|
+
> security patches. This package is maintained for existing Vue 2 apps; new
|
|
38
|
+
> projects should start on Vue 3 with `vue3-klasha`.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install vue-klasha
|
|
44
|
+
# vue is a peer dependency
|
|
45
|
+
npm install vue@^2.7
|
|
15
46
|
```
|
|
16
47
|
|
|
17
|
-
|
|
48
|
+
or via CDN:
|
|
18
49
|
|
|
19
|
-
```
|
|
20
|
-
<!-- Vue -->
|
|
21
|
-
<script src="https://unpkg.com/vue/dist/vue.js"></script>
|
|
22
|
-
<!--
|
|
50
|
+
```html
|
|
51
|
+
<!-- Vue 2 -->
|
|
52
|
+
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
|
|
53
|
+
<!-- vue-klasha (UMD) -->
|
|
23
54
|
<script src="https://unpkg.com/vue-klasha/dist/klasha.min.js"></script>
|
|
24
55
|
```
|
|
25
56
|
|
|
26
|
-
|
|
57
|
+
You do **not** need to add a `<script>` tag for Klasha itself.
|
|
58
|
+
`https://js.klasha.com/pay.js` is injected once, automatically, on demand.
|
|
27
59
|
|
|
28
|
-
|
|
60
|
+
## Usage
|
|
29
61
|
|
|
30
|
-
|
|
62
|
+
### Single-file component
|
|
31
63
|
|
|
32
64
|
```vue
|
|
33
65
|
<template>
|
|
34
66
|
<klasha
|
|
35
67
|
:is-test-mode="isTestMode"
|
|
36
|
-
:email="email"
|
|
37
|
-
:phone-number="phoneNumber"
|
|
38
68
|
:merchant-key="merchantKey"
|
|
69
|
+
:business-id="businessId"
|
|
39
70
|
:amount="amount"
|
|
71
|
+
:tx-ref="txRef"
|
|
40
72
|
:source-currency="sourceCurrency"
|
|
41
73
|
:destination-currency="destinationCurrency"
|
|
42
|
-
:
|
|
43
|
-
:
|
|
74
|
+
:email="email"
|
|
75
|
+
:phone-number="phoneNumber"
|
|
44
76
|
:fullname="fullname"
|
|
45
77
|
:payment-type="paymentType"
|
|
46
78
|
:payment-description="paymentDescription"
|
|
79
|
+
:callback-url="callbackUrl"
|
|
47
80
|
:call-back="callBack"
|
|
48
|
-
:on-close="onClose"
|
|
49
81
|
:embed="false"
|
|
82
|
+
@success="onSuccess"
|
|
83
|
+
@error="onError"
|
|
84
|
+
@tx-ref="onGeneratedTxRef"
|
|
50
85
|
>
|
|
51
|
-
<i class="fas fa-money-bill-alt"
|
|
86
|
+
<i class="fas fa-money-bill-alt" />
|
|
52
87
|
Make Payment
|
|
53
88
|
</klasha>
|
|
54
89
|
</template>
|
|
55
90
|
|
|
56
|
-
<script
|
|
91
|
+
<script>
|
|
57
92
|
import klasha from 'vue-klasha';
|
|
93
|
+
|
|
58
94
|
export default {
|
|
59
|
-
components: {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
isTestMode
|
|
65
|
-
|
|
66
|
-
phoneNumber: 'some phoneNumber',
|
|
67
|
-
merchantKey: 'your merchantKey',
|
|
68
|
-
amount: 1000, // in kobo
|
|
69
|
-
sourceCurrency: '' || 'NGN',
|
|
70
|
-
destinationCurrency: '' || 'NGN',,
|
|
71
|
-
txRef: '' + this.makeId(16),
|
|
95
|
+
components: { klasha },
|
|
96
|
+
data() {
|
|
97
|
+
return {
|
|
98
|
+
// true -> Klasha sandbox
|
|
99
|
+
// false -> LIVE gateway, real money
|
|
100
|
+
isTestMode: true,
|
|
101
|
+
merchantKey: process.env.VUE_APP_KLASHA_MERCHANT_KEY,
|
|
72
102
|
businessId: '1',
|
|
73
|
-
|
|
74
|
-
|
|
103
|
+
amount: 1000,
|
|
104
|
+
txRef: 'ORDER-' + Date.now(),
|
|
105
|
+
sourceCurrency: 'NGN',
|
|
106
|
+
destinationCurrency: 'NGN',
|
|
107
|
+
email: 'buyer@example.com',
|
|
108
|
+
phoneNumber: '+2348159991635',
|
|
109
|
+
fullname: 'Ada Lovelace',
|
|
75
110
|
paymentType: '',
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
111
|
+
paymentDescription: '',
|
|
112
|
+
callbackUrl: 'https://shop.example.com/klasha/callback'
|
|
113
|
+
};
|
|
80
114
|
},
|
|
81
115
|
methods: {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
85
|
-
const charactersLength = characters.length;
|
|
86
|
-
for (let i = 0; i < length; i++) {
|
|
87
|
-
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
88
|
-
}
|
|
89
|
-
return result;
|
|
116
|
+
callBack(response) {
|
|
117
|
+
console.log('payment response', response);
|
|
90
118
|
},
|
|
91
|
-
|
|
92
|
-
console.log(response)
|
|
119
|
+
onSuccess(response) {
|
|
120
|
+
console.log('payment response (event)', response);
|
|
121
|
+
},
|
|
122
|
+
onError(error) {
|
|
123
|
+
console.error('klasha failed to load', error);
|
|
124
|
+
},
|
|
125
|
+
onGeneratedTxRef(txRef) {
|
|
126
|
+
// Only fires when you did not supply :tx-ref yourself.
|
|
127
|
+
this.txRef = txRef;
|
|
93
128
|
}
|
|
94
129
|
}
|
|
95
|
-
}
|
|
130
|
+
};
|
|
96
131
|
</script>
|
|
97
132
|
```
|
|
98
133
|
|
|
99
|
-
[
|
|
134
|
+
[Full example](examples/commonjs/App.vue)
|
|
100
135
|
|
|
101
|
-
|
|
136
|
+
### As a plugin
|
|
102
137
|
|
|
103
|
-
```
|
|
138
|
+
```js
|
|
139
|
+
import Vue from 'vue';
|
|
140
|
+
import VueKlasha from 'vue-klasha';
|
|
141
|
+
|
|
142
|
+
Vue.use(VueKlasha); // registers <klasha>
|
|
143
|
+
Vue.use(VueKlasha, { name: 'klasha-pay' }); // or under your own name
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Via CDN
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<div id="app">
|
|
150
|
+
<klasha
|
|
151
|
+
:is-test-mode="isTestMode"
|
|
152
|
+
:merchant-key="merchantKey"
|
|
153
|
+
:amount="amount"
|
|
154
|
+
:tx-ref="txRef"
|
|
155
|
+
:business-id="businessId"
|
|
156
|
+
:email="email"
|
|
157
|
+
:phone-number="phoneNumber"
|
|
158
|
+
:fullname="fullname"
|
|
159
|
+
:call-back="callBack"
|
|
160
|
+
>Make Payment</klasha>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<script>
|
|
104
164
|
new Vue({
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
165
|
+
el: '#app',
|
|
166
|
+
components: {
|
|
167
|
+
// the UMD bundle exposes the component as VueKlasha.default
|
|
168
|
+
klasha: VueKlasha.default
|
|
169
|
+
},
|
|
170
|
+
data: function () {
|
|
171
|
+
return {
|
|
172
|
+
isTestMode: true,
|
|
173
|
+
merchantKey: 'YOUR_TEST_MERCHANT_KEY',
|
|
174
|
+
amount: 1000,
|
|
175
|
+
txRef: 'ORDER-' + Date.now(),
|
|
176
|
+
businessId: '1',
|
|
177
|
+
email: 'buyer@example.com',
|
|
178
|
+
phoneNumber: '+2348159991635',
|
|
179
|
+
fullname: 'Ada Lovelace'
|
|
180
|
+
};
|
|
181
|
+
},
|
|
182
|
+
methods: {
|
|
183
|
+
callBack: function (response) { console.log(response); }
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
</script>
|
|
187
|
+
```
|
|
110
188
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
189
|
+
[Full CDN example](examples/index.html)
|
|
190
|
+
|
|
191
|
+
## Props
|
|
192
|
+
|
|
193
|
+
| Prop | Type | Required | Default | Description |
|
|
194
|
+
| --- | --- | --- | --- | --- |
|
|
195
|
+
| `merchantKey` | `String` | ✅ | — | Merchant key from your Klasha dashboard. |
|
|
196
|
+
| `amount` | `Number` | ✅ | — | Amount in the source currency's minor unit. |
|
|
197
|
+
| `callBack` | `Function` | ✅ | noop | Called with the gateway response. |
|
|
198
|
+
| `isTestMode` | `Boolean` | | `true` | `true` = sandbox, `false` = **live gateway, real money**. Forwarded as the 9th `KlashaClient` argument. |
|
|
199
|
+
| `businessId` | `String \| Number` | | `''` | Business id from your dashboard (falls back to `1`). |
|
|
200
|
+
| `txRef` | `String` | | `''` | Your transaction reference. Generated and emitted as `tx-ref` if omitted. |
|
|
201
|
+
| `sourceCurrency` | `String` | | `'NGN'` | Currency the customer pays in. |
|
|
202
|
+
| `destinationCurrency` | `String` | | `'NGN'` | Currency you are settled in. |
|
|
203
|
+
| `email` | `String` | | `''` | Customer email. |
|
|
204
|
+
| `phoneNumber` | `String` | | `''` | Customer phone. Sent to the gateway as `kit.phone`. |
|
|
205
|
+
| `fullname` | `String` | | `''` | Customer name. |
|
|
206
|
+
| `paymentType` | `String` | | `''` | Sent to the gateway as `kit.productType`. |
|
|
207
|
+
| `paymentDescription` | `String` | | `''` | Free-text description. |
|
|
208
|
+
| `callbackUrl` | `String` | | `''` | Merchant callback URL. |
|
|
209
|
+
| `metadata` | `Object` | | `{}` | Extra data passed through on the kit. |
|
|
210
|
+
| `embed` | `Boolean` | | `false` | Render an inline container instead of a button and start on mount. |
|
|
211
|
+
| `containerId` | `String` | | auto | Explicit DOM id for the checkout container. Leave unset for a unique per-instance id. |
|
|
212
|
+
| `init` | `Function` | | noop | Called just before checkout opens. |
|
|
213
|
+
| `onClose` | `Function` | | noop | Accepted for API compatibility. `pay.js` does not currently expose a "modal closed" hook, so **this is not invoked by the gateway**. |
|
|
214
|
+
|
|
215
|
+
## Events
|
|
216
|
+
|
|
217
|
+
| Event | Payload | When |
|
|
218
|
+
| --- | --- | --- |
|
|
219
|
+
| `ready` | — | `pay.js` finished loading. |
|
|
220
|
+
| `success` | gateway response | Same payload as `callBack`. |
|
|
221
|
+
| `error` | `Error` | The script failed to load, or checkout could not be started. |
|
|
222
|
+
| `tx-ref` | `String` | A reference was generated because you did not supply `txRef`. Record it. |
|
|
223
|
+
|
|
224
|
+
## Test mode vs live mode
|
|
225
|
+
|
|
226
|
+
`isTestMode` is the **only** thing that selects the environment — there is one
|
|
227
|
+
script URL for both. Internally it chooses between Klasha's development and
|
|
228
|
+
production gateway hosts.
|
|
229
|
+
|
|
230
|
+
```vue
|
|
231
|
+
<klasha :is-test-mode="true" ... /> <!-- sandbox -->
|
|
232
|
+
<klasha :is-test-mode="false" ... /> <!-- LIVE, real money -->
|
|
141
233
|
```
|
|
142
234
|
|
|
143
|
-
|
|
235
|
+
It defaults to `true` so that a missing or mistyped value can never charge a real
|
|
236
|
+
card. Bind a real boolean — a string such as `"false"` is truthy in JavaScript
|
|
237
|
+
(the component casts with `Boolean()` as a safety net, but Vue will also warn on
|
|
238
|
+
a type mismatch).
|
|
239
|
+
|
|
240
|
+
**Never hard-code a live merchant key in client source or commit it.** Read it
|
|
241
|
+
from your build-time environment.
|
|
144
242
|
|
|
145
|
-
|
|
243
|
+
## Styling the button
|
|
146
244
|
|
|
147
|
-
|
|
245
|
+
The default button carries the class `klashaPayButtonStyle`:
|
|
246
|
+
|
|
247
|
+
```html
|
|
148
248
|
<style>
|
|
149
|
-
.klashaPayButtonStyle{
|
|
150
|
-
background-color: #4CAF50;
|
|
249
|
+
.klashaPayButtonStyle {
|
|
250
|
+
background-color: #4CAF50;
|
|
151
251
|
border-radius: 20px;
|
|
252
|
+
border: 0;
|
|
152
253
|
color: white;
|
|
254
|
+
cursor: pointer;
|
|
153
255
|
padding: 15px 32px;
|
|
154
|
-
text-align: center;
|
|
155
|
-
text-decoration: none;
|
|
156
|
-
display: inline-block;
|
|
157
256
|
font-size: 16px;
|
|
158
257
|
}
|
|
159
258
|
</style>
|
|
160
|
-
|
|
161
259
|
```
|
|
162
260
|
|
|
163
|
-
|
|
261
|
+
In `embed` mode the rendered container carries the class `klashaEmbedContainer`.
|
|
164
262
|
|
|
165
|
-
|
|
263
|
+
## Development
|
|
166
264
|
|
|
167
|
-
|
|
265
|
+
```bash
|
|
266
|
+
npm install
|
|
267
|
+
npm run lint # eslint
|
|
268
|
+
npm test # jest + @vue/test-utils
|
|
269
|
+
npm run build # UMD -> dist/klasha.min.js, ESM -> dist/klasha.esm.js
|
|
270
|
+
npm run dev # webpack-dev-server against examples/commonjs
|
|
271
|
+
```
|
|
168
272
|
|
|
169
|
-
|
|
273
|
+
The test suite mocks `window.KlashaClient` and asserts on the constructor
|
|
274
|
+
arguments. It cannot complete a real payment — that requires live merchant
|
|
275
|
+
credentials.
|
|
170
276
|
|
|
171
277
|
## Contributing
|
|
172
278
|
|
|
173
|
-
1. Fork it
|
|
279
|
+
1. Fork it
|
|
174
280
|
2. Create your feature branch: `git checkout -b feature-name`
|
|
175
281
|
3. Commit your changes: `git commit -am 'Some commit message'`
|
|
176
282
|
4. Push to the branch: `git push origin feature-name`
|
|
177
|
-
5. Submit a pull request
|
|
283
|
+
5. Submit a pull request 😉
|
|
178
284
|
|
|
179
285
|
## How can I thank you?
|
|
180
286
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
Don't forget to [follow me on twitter](https://twitter.com/dansteveade)!
|
|
184
|
-
|
|
185
|
-
Thanks!
|
|
287
|
+
Star the repo, or share it. Don't forget to
|
|
288
|
+
[follow me on twitter](https://twitter.com/dansteveade)!
|
|
186
289
|
|
|
187
|
-
Dansteve Adekanbi.
|
|
290
|
+
Dansteve Adekanbi — [dansteve.com](https://dansteve.com)
|
|
188
291
|
|
|
189
292
|
## License
|
|
190
293
|
|
|
191
|
-
|
|
294
|
+
MIT — see [LICENSE](LICENSE).
|