vue-klasha 0.0.5 → 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 CHANGED
@@ -1,191 +1,294 @@
1
- # Klasha Component for Vue 2.x
1
+ # vue-klasha
2
2
 
3
- A Vue Plugin for Klasha payment gateway.
3
+ Klasha payment gateway component for **Vue 2.x**.
4
4
 
5
- ### Demo
5
+ [![npm](https://img.shields.io/npm/v/vue-klasha.svg)](https://www.npmjs.com/package/vue-klasha)
6
+ [![license](https://img.shields.io/npm/l/vue-klasha.svg)](LICENSE)
6
7
 
7
- ![Demo Image](vue-klasha.png?raw=true "Demo Image")
8
+ ---
8
9
 
9
- ### Install
10
+ ## ⚠️ Upgrade immediately if you are on 0.0.x
10
11
 
11
- #### NPM
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
- npm install vue vue-klasha --save
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
- #### Javascript via CDN
48
+ or via CDN:
18
49
 
19
- ```javascript 1.8
20
- <!-- Vue -->
21
- <script src="https://unpkg.com/vue/dist/vue.js"></script>
22
- <!-- Vue-Klasha -->
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
- ### Usage
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
- #### Via NPM
60
+ ## Usage
29
61
 
30
- ###### my-compnent.vue sample
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
- :tx-ref="txRef"
43
- :business-id="businessId"
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"></i>
86
+ <i class="fas fa-money-bill-alt" />
52
87
  Make Payment
53
88
  </klasha>
54
89
  </template>
55
90
 
56
- <script type="text/javascript">
91
+ <script>
57
92
  import klasha from 'vue-klasha';
93
+
58
94
  export default {
59
- components: {
60
- klasha
61
- },
62
- data(){
63
- return{
64
- isTestMode : true,
65
- email: 'some data',
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
- fullname: 'some fullname',
74
- paymentDescription: '',
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
- computed: {
79
-
111
+ paymentDescription: '',
112
+ callbackUrl: 'https://shop.example.com/klasha/callback'
113
+ };
80
114
  },
81
115
  methods: {
82
- makeId(length) {
83
- let result = '';
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
- callBack: function(response){
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
- [Usage Example via NPM or Yarn](examples/commonjs/App.vue)
134
+ [Full example](examples/commonjs/App.vue)
100
135
 
101
- #### via CDN
136
+ ### As a plugin
102
137
 
103
- ```javascript 1.8
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
- el: '#app',
106
- components:{
107
- 'klasha': VueKlasha.default
108
- },
109
- computed: {
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
- methods: {
113
- makeId(length) {
114
- let result = '';
115
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
116
- const charactersLength = characters.length;
117
- for (let i = 0; i < length; i++) {
118
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
119
- }
120
- return result;
121
- },
122
- callBack: function(response){
123
- console.log(response)
124
- }
125
- },
126
- data: {
127
- isTestMode : true,
128
- email: 'some data',
129
- phoneNumber: 'some phoneNumber',
130
- merchantKey: 'your merchantKey',
131
- amount: 1000, // in kobo
132
- sourceCurrency: '' || 'NGN',
133
- destinationCurrency: '' || 'NGN',,
134
- txRef: '' + this.makeId(16),
135
- businessId: '1',
136
- fullname: 'some fullname',
137
- paymentDescription: '',
138
- paymentType: '',
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
- ### Styling button
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
- Add style call klashaPayButtonStyle
243
+ ## Styling the button
146
244
 
147
- ``` html
245
+ The default button carries the class `klashaPayButtonStyle`:
246
+
247
+ ```html
148
248
  <style>
149
- .klashaPayButtonStyle{
150
- background-color: #4CAF50; /* Green */
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
- [Usage Example via CDN](examples/index.html)
261
+ In `embed` mode the rendered container carries the class `klashaEmbedContainer`.
164
262
 
165
- Please checkout [Klasha Documentation](https://documenter.getpostman.com/view/8963555/TzJoFgHh) for other available options you can add to the
263
+ ## Development
166
264
 
167
- ## Deployment
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
- REMEMBER TO CHANGE THE *merchantKey* WHEN DEPLOYING ON A LIVE/PRODUCTION SYSTEM
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
- Why not star the github repo? I'd love the attention! Why not share the link for this repository on Twitter or Any Social Media? Spread the word!
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
- This project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details
294
+ MIT see [LICENSE](LICENSE).