zakkistore-sdk 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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +99 -0
  3. data/lib/zakkistore-sdk.rb +293 -0
  4. metadata +47 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ data.tar.gz: d4913d90836c0d62b6bba66b1550e504f517d69b1bb78e061cf1792a81c1d8ae
4
+ metadata.gz: 8d571e2886f5b7ac3d175c4cc97edcdf9abc319194dbb1d75a8dfb785b12a090
5
+ SHA512:
6
+ data.tar.gz: 3fe7d945bd168df9d2cb0827216c4b51d8d6709748a84454592544feb5990d3c40d3e5137dbbb172a69933974714203cde3aa64dc2cf62f7f1a1139a1ab0fa42
7
+ metadata.gz: 7399e7cec6aa598167452c2bc632caddf206a5d93bd02d1982326b35fc6a65657c56e0b8c16b14a31094a174de48a60dca844f7120201c818471688a573ba83f
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # šŸ’Ž Zakkistore SDK for Ruby
2
+
3
+ **Official B2B Client Library for Zakki Store API Gateway**
4
+
5
+ Pustaka Ruby resmi untuk memudahkan integrasi layanan Host-to-Host (H2H) prabayar/pascabayar, payment gateway QRIS otomatis, perbankan Virtual Account (VA), Noktel OTP virtual, mining reward, dan gacha koin Zakki Store ke dalam proyek Ruby Anda (Rails, Sinatra, Hanami, bot Telegram/Discord, dll).
6
+
7
+ ---
8
+
9
+ ## šŸš€ Instalasi & Inisialisasi
10
+
11
+ Tambahkan pustaka ini ke dalam `Gemfile` Anda:
12
+
13
+ ```ruby
14
+ gem 'zakkistore-sdk'
15
+ ```
16
+
17
+ Atau instal secara manual via RubyGems:
18
+
19
+ ```bash
20
+ gem install zakkistore-sdk
21
+ ```
22
+
23
+ ### Inisialisasi Klien
24
+
25
+ ```ruby
26
+ require 'zakkistore-sdk'
27
+
28
+ # Inisialisasi klien SDK
29
+ zakki = ZakkiStore.new(
30
+ "https://qris.zakki.store", # URL API Server
31
+ "API_TOKEN_ANDA", # Token API
32
+ "IBO99", # iduser
33
+ "member@gmail.com", # email
34
+ "123456", # PIN transaksi (Wajib untuk tabung & tarik)
35
+ true # Aktifkan penarikan saldo VA otomatis ke aplikasi!
36
+ )
37
+ ```
38
+
39
+ ---
40
+
41
+ ## šŸ› ļø Fitur Unggulan
42
+
43
+ ### šŸ”„ Auto-Withdraw Saldo VA
44
+ Jika opsi `auto_withdraw: true` diaktifkan, SDK akan memicu penarikan dana VA bank otomatis secara *real-time* menjadi saldo utama aplikasi (BukaOlshop) ketika fungsi `checkbank()` dipanggil.
45
+
46
+ ### šŸ’” Dual-Flow Pascabayar & Bebas Nominal
47
+ * **Pascabayar (PLN/BPJS/PDAM):** Inquiry tagihan terlebih dahulu, lalu bayar dengan format tujuan `[ID_Pelanggan].[Nominal_Tagihan]` (Contoh: `122345678901.150000`).
48
+ * **E-Wallet Bebas Nominal:** Kirim transfer E-Wallet nominal kustom dengan format tujuan `[No_HP].[Nominal]` (Contoh: `08123456789.25000`).
49
+
50
+ ---
51
+
52
+ ## šŸ“‘ Daftar Referensi Metode Lengkap
53
+
54
+ SDK Ruby ini mendukung secara penuh seluruh **25 fungsi resmi** dengan nama dan perilaku yang konsisten dengan SDK versi Node.js (NPM):
55
+
56
+ ### 1. Payment Gateway (QRIS Top Up)
57
+ * `zakki.topup(nominal)` — Membuat QRIS dinamis instan dengan nominal kode unik.
58
+ * `zakki.cektopup(idtopup)` — Cek status pembayaran QRIS.
59
+ * `zakki.cancel(id_transaksi, all_pending)` — Batalkan transaksi pending (Daftar pending, batal satu, atau batal massal).
60
+
61
+ ### 2. Transaksi H2H
62
+ * `zakki.listkode(jenis, product_type)` — Katalog kode produk aktif, deskripsi, dan harga.
63
+ * `zakki.h2h(kode, tujuan, refID)` — Mengirim order transaksi H2H (Mendukung hash argumen).
64
+ * `zakki.cekh2h(id_trx)` — Cek detail status pengisian, SN, dan harga beli order H2H.
65
+ * `zakki.myh2h()` — Mengambil 20 riwayat pembelian H2H terupdate.
66
+
67
+ ### 3. Perbankan & Transfer VA
68
+ * `zakki.checkbank()` — Cek saldo, VA member, mutasi, dan pemicu Auto-Withdraw.
69
+ * `zakki.checkname(number)` — Verifikasi nama asli pemilik VA Bank Zakki tujuan.
70
+ * `zakki.transfer(to, amount)` — Transfer saldo antar Virtual Account member Bank Zakki (Mendukung hash argumen).
71
+ * `zakki.tabung(jumlah)` — Menabung / deposit saldo dari aplikasi utama (BukaOlshop) ke Bank (butuh PIN).
72
+ * `zakki.tarik(jumlah)` — Menarik dana tabungan ke saldo aplikasi (butuh PIN).
73
+ * `zakki.checkmutasi(mutasi_type)` — Riwayat mutasi Tarik/Tabung (`tarik`, `tabung`, `all`).
74
+
75
+ ### 4. Noktel Marketplace (OTP Virtual)
76
+ * `zakki.noktelStok()` — Cek stok nomor virtual yang ready.
77
+ * `zakki.noktelBuy(category)` — Membeli nomor virtual baru untuk OTP.
78
+ * `zakki.noktelGetOtp(account_id)` — Menarik kode OTP Telegram secara real-time.
79
+ * `zakki.noktelCancel(invoice_id)` — Membatalkan nomor yang pending OTP & auto-refund.
80
+ * `zakki.noktelHistory()` — Mengambil daftar riwayat pembelian Noktel.
81
+
82
+ ### 5. Reward Komputasi & Game
83
+ * `zakki.cekmining()` — Cek status kesulitan global, block reward, dan miner aktif.
84
+ * `zakki.mymining()` — Riwayat koin mining SHA256 milik akun Anda.
85
+ * `zakki.cekgacha()` — Statistik poin, kemenangan, dan keuntungan gacha member.
86
+
87
+ ### 6. Keamanan & Utilitas
88
+ * `zakki.whitelistip(ip)` — Whitelist IP server Anda untuk otorisasi API H2H.
89
+ * `zakki.delwhitelistip(ip)` — Hapus IP server dari whitelist.
90
+ * `zakki.leaderboard(limit, period)` — Mengambil peringkat sultan topup teraktif.
91
+ * `zakki.status()` — Informasi beban CPU, metrik finansial, dan kesehatan sistem.
92
+
93
+ ---
94
+
95
+ ## šŸ›”ļø Protokol Keamanan API
96
+
97
+ > [!WARNING]
98
+ > **Selalu jalankan SDK ini di sisi backend (Server-side)!**
99
+ > Jangan pernah mengekspos API Token dan PIN Anda langsung di frontend aplikasi / browser klien publik demi mencegah potensi pencurian saldo.
@@ -0,0 +1,293 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ class ZakkiStore
6
+ attr_accessor :base_url, :token, :iduser, :email, :pin, :auto_withdraw
7
+
8
+ def initialize(base_url = "https://qris.zakki.store", token = nil, iduser = nil, email = nil, pin = nil, auto_withdraw = false)
9
+ # Smart detection if token is placed in base_url parameter
10
+ if base_url && !base_url.start_with?("http://") && !base_url.start_with?("https://") && token.nil?
11
+ token = base_url
12
+ base_url = "https://qris.zakki.store"
13
+ end
14
+
15
+ raise ArgumentError, "token wajib disertakan dalam konfigurasi SDK." if token.nil? || token.empty?
16
+ raise ArgumentError, "base_url wajib disertakan dalam konfigurasi SDK." if base_url.nil? || base_url.empty?
17
+
18
+ @base_url = base_url.chomp('/')
19
+ @token = token
20
+ @iduser = iduser
21
+ @email = email
22
+ @pin = pin
23
+ @auto_withdraw = !!auto_withdraw
24
+ end
25
+
26
+ def enable_auto_withdraw(status)
27
+ @auto_withdraw = !!status
28
+ end
29
+
30
+ def enableAutoWithdraw(status)
31
+ enable_auto_withdraw(status)
32
+ end
33
+
34
+ # ==========================================================
35
+ # --- 1. PAYMENT GATEWAY (QRIS TOPUP) ---
36
+ # ==========================================================
37
+
38
+ def topup(nominal)
39
+ _request('/topup', 'POST', {
40
+ "token" => @token,
41
+ "nominal" => nominal.to_i
42
+ })
43
+ end
44
+
45
+ def cektopup(idtopup)
46
+ _request('/cektopup', 'GET', {
47
+ "idtopup" => idtopup
48
+ })
49
+ end
50
+
51
+ def cancel(id_transaksi = nil, all_pending = false)
52
+ if id_transaksi.is_a?(TrueClass) || id_transaksi.is_a?(FalseClass)
53
+ all_pending = id_transaksi
54
+ id_transaksi = nil
55
+ end
56
+
57
+ payload = { "token" => @token }
58
+ payload["id_transaksi"] = id_transaksi if id_transaksi
59
+ payload["all"] = true if all_pending
60
+ _request('/cancel', 'POST', payload)
61
+ end
62
+
63
+ # ==========================================================
64
+ # --- 2. TRANSAKSI H2H (HOST-TO-HOST) ---
65
+ # ==========================================================
66
+
67
+ def listkode(jenis = nil, product_type = nil)
68
+ payload = {}
69
+ payload["jenis"] = jenis if jenis
70
+ payload["type"] = product_type if product_type
71
+ _request('/listkode', 'GET', payload)
72
+ end
73
+
74
+ def h2h(kode, tujuan = nil, ref_id = nil)
75
+ if kode.is_a?(Hash)
76
+ payload = kode
77
+ kode = payload[:kode] || payload["kode"]
78
+ tujuan = payload[:tujuan] || payload["tujuan"]
79
+ ref_id = payload[:refID] || payload["refID"] || payload[:ref_id] || payload["ref_id"]
80
+ end
81
+
82
+ _request('/h2h', 'POST', {
83
+ "token" => @token,
84
+ "kode" => kode,
85
+ "tujuan" => tujuan,
86
+ "refID" => ref_id
87
+ })
88
+ end
89
+
90
+ def cekh2h(id_trx)
91
+ _request('/cekh2h', 'GET', { "id" => id_trx })
92
+ end
93
+
94
+ def myh2h
95
+ _request('/myh2h', 'GET', { "token" => @token })
96
+ end
97
+
98
+ # ==========================================================
99
+ # --- 3. PERBANKAN & TRANSFER SALDO ---
100
+ # ==========================================================
101
+
102
+ def checkbank
103
+ payload = { "token" => @token }
104
+ payload["iduser"] = @iduser if @iduser
105
+ payload["email"] = @email if @email
106
+
107
+ bank_res = _request('/checkbank', 'GET', payload)
108
+
109
+ if @auto_withdraw && bank_res["data"] && bank_res["data"]["bank_detail"]
110
+ bank_detail = bank_res["data"]["bank_detail"]
111
+ balance = (bank_detail["balance"] || 0).to_f
112
+
113
+ if balance > 0
114
+ begin
115
+ withdraw_res = tarik(balance.to_i)
116
+ bank_res = _request('/checkbank', 'GET', payload)
117
+ bank_res["auto_withdraw_executed"] = true
118
+ bank_res["auto_withdraw_amount"] = balance.to_i
119
+ bank_res["auto_withdraw_message"] = withdraw_res["message"] || "Auto-withdraw berhasil dijalankan."
120
+ rescue => err
121
+ bank_res["auto_withdraw_executed"] = false
122
+ bank_res["auto_withdraw_error"] = err.message
123
+ end
124
+ end
125
+ end
126
+
127
+ bank_res
128
+ end
129
+
130
+ def checkname(number)
131
+ _request('/checkname', 'GET', { "number" => number.to_s.strip })
132
+ end
133
+
134
+ def transfer(to, amount = nil)
135
+ if to.is_a?(Hash)
136
+ payload = to
137
+ to = payload[:to] || payload["to"]
138
+ amount = payload[:amount] || payload["amount"]
139
+ end
140
+
141
+ _request('/transfer', 'POST', {
142
+ "token" => @token,
143
+ "to" => to,
144
+ "amount" => amount.to_i
145
+ })
146
+ end
147
+
148
+ def tabung(jumlah)
149
+ raise RuntimeError, "[ZakkiStore SDK Error] PIN transaksi diperlukan untuk melakukan transaksi tabung." unless @pin
150
+ payload = {
151
+ "token" => @token,
152
+ "jumlah" => jumlah.to_i,
153
+ "pin" => @pin
154
+ }
155
+ payload["iduser"] = @iduser if @iduser
156
+ payload["email"] = @email if @email
157
+ _request('/tabung', 'POST', payload)
158
+ end
159
+
160
+ def tarik(jumlah)
161
+ raise RuntimeError, "[ZakkiStore SDK Error] PIN transaksi diperlukan untuk melakukan transaksi tarik." unless @pin
162
+ payload = {
163
+ "token" => @token,
164
+ "jumlah" => jumlah.to_i,
165
+ "pin" => @pin
166
+ }
167
+ payload["iduser"] = @iduser if @iduser
168
+ payload["email"] = @email if @email
169
+ _request('/tarik', 'POST', payload)
170
+ end
171
+
172
+ def checkmutasi(mutasi_type = "all")
173
+ payload = {
174
+ "token" => @token,
175
+ "type" => mutasi_type
176
+ }
177
+ payload["iduser"] = @iduser if @iduser
178
+ payload["email"] = @email if @email
179
+ _request('/checkmutasi', 'GET', payload)
180
+ end
181
+
182
+ # ==========================================================
183
+ # --- 4. NOKTEL MARKETPLACE (OTP VIRTUAL) ---
184
+ # ==========================================================
185
+
186
+ def noktelStok
187
+ _request('/noktel/stok', 'GET', { "token" => @token })
188
+ end
189
+
190
+ def noktelBuy(category)
191
+ _request('/noktel/buy', 'POST', {
192
+ "token" => @token,
193
+ "category" => category.to_s.strip
194
+ })
195
+ end
196
+
197
+ def noktelGetOtp(account_id)
198
+ _request('/noktel/getotp', 'GET', {
199
+ "token" => @token,
200
+ "account_id" => account_id.to_s.strip
201
+ })
202
+ end
203
+
204
+ def noktelCancel(invoice_id)
205
+ _request('/noktel/cancel', 'POST', {
206
+ "token" => @token,
207
+ "invoice_id" => invoice_id.to_s.strip
208
+ })
209
+ end
210
+
211
+ def noktelHistory
212
+ _request('/noktel/history', 'GET', { "token" => @token })
213
+ end
214
+
215
+ # ==========================================================
216
+ # --- 5. REWARD KOMPUTASI & UTILITY ---
217
+ # ==========================================================
218
+
219
+ def cekmining
220
+ _request('/cekmining', 'GET', { "token" => @token })
221
+ end
222
+
223
+ def mymining
224
+ _request('/mymining', 'GET', { "token" => @token })
225
+ end
226
+
227
+ def cekgacha
228
+ _request('/cekgacha', 'GET', { "token" => @token })
229
+ end
230
+
231
+ def whitelistip(ip)
232
+ _request('/whitelistip', 'POST', {
233
+ "token" => @token,
234
+ "ip" => ip.to_s.strip
235
+ })
236
+ end
237
+
238
+ def delwhitelistip(ip)
239
+ _request('/delwhitelistip', 'POST', {
240
+ "token" => @token,
241
+ "ip" => ip.to_s.strip
242
+ })
243
+ end
244
+
245
+ def leaderboard(limit = 10, period = "all")
246
+ _request('/leaderboard', 'GET', {
247
+ "limit" => limit.to_i,
248
+ "period" => period.to_s.strip
249
+ })
250
+ end
251
+
252
+ def status
253
+ _request('/status', 'GET')
254
+ end
255
+
256
+ private
257
+
258
+ def _request(endpoint, method = 'GET', data = nil)
259
+ uri = URI.parse("#{@base_url}#{endpoint}")
260
+
261
+ http = Net::HTTP.new(uri.host, uri.port)
262
+ http.use_ssl = true if uri.scheme == 'https'
263
+
264
+ headers = { 'Content-Type' => 'application/json' }
265
+
266
+ if method.upcase == 'GET'
267
+ if data && !data.empty?
268
+ uri.query = URI.encode_www_form(data)
269
+ end
270
+ request = Net::HTTP::Get.new(uri.request_uri, headers)
271
+ else
272
+ request = Net::HTTP::Post.new(uri.request_uri, headers)
273
+ request.body = data.to_json if data
274
+ end
275
+
276
+ begin
277
+ response = http.request(request)
278
+ res_json = JSON.parse(response.body) rescue { "message" => response.body }
279
+
280
+ if response.code.to_i != 200 && response.code.to_i != 201
281
+ err_msg = res_json["message"] || "HTTP Error! Status: #{response.code}"
282
+ if response.code.to_i == 403 || err_msg.downcase.include?("ip")
283
+ err_msg += "\nāš ļø [IP BLOCKED / UNREGISTERED] IP Anda diblokir atau belum terdaftar di whitelist API. Silakan hubungi developer via WhatsApp (https://wa.me/6283844082339) atau Telegram (https://t.me/zakki_store) untuk mendapatkan bantuan."
284
+ end
285
+ raise RuntimeError, "[ZakkiStore SDK Error] #{err_msg}"
286
+ end
287
+
288
+ res_json
289
+ rescue => e
290
+ raise RuntimeError, "[ZakkiStore SDK Error] Koneksi Gagal: #{e.message}"
291
+ end
292
+ end
293
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zakkistore-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - ZakkiXD
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-06-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Mempermudah integrasi layanan gerbang pembayaran (Payment Gateway) QRIS dan H2H Zakki Store.
14
+ email:
15
+ - b2b_partner@example.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - lib/zakkistore-sdk.rb
22
+ homepage: https://github.com/MrLow12/zakkistore-sdk-ruby
23
+ licenses:
24
+ - MIT
25
+ metadata:
26
+ homepage_uri: https://github.com/MrLow12/zakkistore-sdk-ruby
27
+ source_code_uri: https://github.com/MrLow12/zakkistore-sdk-ruby
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.4.0
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubygems_version: 3.2.22
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Official Ruby SDK Client Library for Zakki Store B2B API Gateway
47
+ test_files: []