bayarcash 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.
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bayarcash
4
+ # Constant-time string comparison helpers, mirroring PHP's `hash_equals`.
5
+ #
6
+ # This is the Ruby equivalent of `Rack::Utils.secure_compare` /
7
+ # `ActiveSupport::SecurityUtils.secure_compare` and is used to compare callback
8
+ # checksums so that verification is not vulnerable to timing attacks.
9
+ module SecurityUtils
10
+ module_function
11
+
12
+ # Compare two strings in (length-dependent but content-) constant time.
13
+ #
14
+ # @param left [String]
15
+ # @param right [String]
16
+ # @return [Boolean] true only when the two strings are byte-for-byte equal
17
+ def secure_compare(left, right)
18
+ left = left.to_s
19
+ right = right.to_s
20
+
21
+ return false unless left.bytesize == right.bytesize
22
+
23
+ if OpenSSL.respond_to?(:fixed_length_secure_compare)
24
+ begin
25
+ return OpenSSL.fixed_length_secure_compare(left, right)
26
+ rescue StandardError
27
+ # fall through to the manual implementation
28
+ end
29
+ end
30
+
31
+ l = left.unpack("C*")
32
+ res = 0
33
+ right.each_byte { |byte| res |= byte ^ l.shift }
34
+ res.zero?
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bayarcash
4
+ # Small helpers that reproduce PHP string/array semantics the gateway relies on.
5
+ module Util
6
+ module_function
7
+
8
+ # Cast a value to a string exactly the way PHP's `implode`/`(string)` cast does.
9
+ #
10
+ # This matters for byte-compatible checksum generation: `nil` becomes an empty
11
+ # string, booleans become "1"/"" and everything else uses its string form.
12
+ #
13
+ # @param value [Object]
14
+ # @return [String]
15
+ def php_string(value)
16
+ case value
17
+ when nil then ""
18
+ when true then "1"
19
+ when false then ""
20
+ else value.to_s
21
+ end
22
+ end
23
+
24
+ # Whether a decoded JSON value is "falsy" in the PHP sense.
25
+ #
26
+ # Mirrors PHP's `json_decode($body, true) ?: $body` short-circuit so that empty
27
+ # or falsy payloads fall back to the raw response body.
28
+ #
29
+ # @param value [Object]
30
+ # @return [Boolean]
31
+ def php_falsy?(value)
32
+ case value
33
+ when nil, false then true
34
+ when 0, 0.0 then true
35
+ when "", "0" then true
36
+ when Array, Hash then value.empty?
37
+ else false
38
+ end
39
+ end
40
+
41
+ # URL-encode a component the way PHP's `urlencode` does (spaces become "+").
42
+ #
43
+ # @param value [Object]
44
+ # @return [String]
45
+ def url_encode(value)
46
+ URI.encode_www_form_component(php_string(value))
47
+ end
48
+
49
+ # Build a URL-encoded query string, reproducing PHP's `http_build_query`
50
+ # (RFC1738 encoding, bracket notation for nested arrays and hashes).
51
+ #
52
+ # @param params [Hash]
53
+ # @param prefix [String, nil]
54
+ # @return [String]
55
+ def build_query(params, prefix = nil)
56
+ parts = []
57
+
58
+ params.each do |key, value|
59
+ composed_key = prefix ? "#{prefix}[#{key}]" : key.to_s
60
+
61
+ case value
62
+ when Hash
63
+ nested = build_query(value, composed_key)
64
+ parts << nested unless nested.empty?
65
+ when Array
66
+ value.each_with_index do |item, index|
67
+ if item.is_a?(Hash) || item.is_a?(Array)
68
+ nested = build_query({ index => item }, composed_key)
69
+ parts << nested unless nested.empty?
70
+ else
71
+ parts << "#{url_encode("#{composed_key}[#{index}]")}=#{url_encode(item)}"
72
+ end
73
+ end
74
+ else
75
+ parts << "#{url_encode(composed_key)}=#{url_encode(value)}"
76
+ end
77
+ end
78
+
79
+ parts.join("&")
80
+ end
81
+
82
+ # Parse a JSON string, returning nil on failure instead of raising.
83
+ #
84
+ # @param body [String]
85
+ # @return [Object, nil]
86
+ def safe_json(body)
87
+ JSON.parse(body)
88
+ rescue JSON::ParserError, TypeError
89
+ nil
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bayarcash
4
+ VERSION = "1.0.0"
5
+ end
data/lib/bayarcash.rb ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "openssl"
5
+ require "uri"
6
+ require "date"
7
+ require "faraday"
8
+ require "faraday/multipart"
9
+
10
+ require_relative "bayarcash/version"
11
+ require_relative "bayarcash/errors"
12
+ require_relative "bayarcash/security_utils"
13
+ require_relative "bayarcash/util"
14
+
15
+ require_relative "bayarcash/resources/resource"
16
+ require_relative "bayarcash/resources/payment_intent_resource"
17
+ require_relative "bayarcash/resources/transaction_resource"
18
+ require_relative "bayarcash/resources/portal_resource"
19
+ require_relative "bayarcash/resources/fpx_bank_resource"
20
+ require_relative "bayarcash/resources/fpx_direct_debit_resource"
21
+ require_relative "bayarcash/resources/fpx_direct_debit_application_resource"
22
+
23
+ require_relative "bayarcash/fpx"
24
+ require_relative "bayarcash/fpx_direct_debit"
25
+ require_relative "bayarcash/duit_now/dobw"
26
+
27
+ require_relative "bayarcash/checksum_generator"
28
+ require_relative "bayarcash/callback_verifications"
29
+ require_relative "bayarcash/makes_http_requests"
30
+ require_relative "bayarcash/fpx_direct_debit_payment_intent"
31
+ require_relative "bayarcash/manual_bank_transfer"
32
+
33
+ require_relative "bayarcash/client"
34
+
35
+ # Bayarcash Ruby SDK.
36
+ #
37
+ # The primary entry point is {Bayarcash::Client}, an expressive, framework-agnostic
38
+ # client for the Bayarcash Payment Gateway API. It mirrors the public surface of the
39
+ # official PHP SDK while remaining idiomatic Ruby.
40
+ module Bayarcash
41
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bayarcash
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Web Impian
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.10'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '1.10'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '3.0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: faraday-multipart
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '1.0'
39
+ - - "<"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.0'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '1.0'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '2.0'
52
+ - !ruby/object:Gem::Dependency
53
+ name: rspec
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '3.12'
59
+ type: :development
60
+ prerelease: false
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '3.12'
66
+ - !ruby/object:Gem::Dependency
67
+ name: webmock
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '3.19'
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '3.19'
80
+ - !ruby/object:Gem::Dependency
81
+ name: rake
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '13.0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '13.0'
94
+ description: An expressive, framework-agnostic Ruby client for the Bayarcash Payment
95
+ Gateway API. Supports API v2 (default) and v3, checksum generation, callback verification,
96
+ FPX Direct Debit, and Manual Bank Transfer.
97
+ email:
98
+ - support@webimpian.com
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - CHANGELOG.md
104
+ - LICENSE
105
+ - README.md
106
+ - bayarcash.gemspec
107
+ - lib/bayarcash.rb
108
+ - lib/bayarcash/callback_verifications.rb
109
+ - lib/bayarcash/checksum_generator.rb
110
+ - lib/bayarcash/client.rb
111
+ - lib/bayarcash/duit_now/dobw.rb
112
+ - lib/bayarcash/errors.rb
113
+ - lib/bayarcash/fpx.rb
114
+ - lib/bayarcash/fpx_direct_debit.rb
115
+ - lib/bayarcash/fpx_direct_debit_payment_intent.rb
116
+ - lib/bayarcash/makes_http_requests.rb
117
+ - lib/bayarcash/manual_bank_transfer.rb
118
+ - lib/bayarcash/resources/fpx_bank_resource.rb
119
+ - lib/bayarcash/resources/fpx_direct_debit_application_resource.rb
120
+ - lib/bayarcash/resources/fpx_direct_debit_resource.rb
121
+ - lib/bayarcash/resources/payment_intent_resource.rb
122
+ - lib/bayarcash/resources/portal_resource.rb
123
+ - lib/bayarcash/resources/resource.rb
124
+ - lib/bayarcash/resources/transaction_resource.rb
125
+ - lib/bayarcash/security_utils.rb
126
+ - lib/bayarcash/util.rb
127
+ - lib/bayarcash/version.rb
128
+ homepage: https://bayarcash.com/
129
+ licenses:
130
+ - MIT
131
+ metadata:
132
+ homepage_uri: https://bayarcash.com/
133
+ source_code_uri: https://github.com/bayarcash/ruby-sdk
134
+ changelog_uri: https://github.com/bayarcash/ruby-sdk/blob/main/CHANGELOG.md
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '2.7'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubygems_version: 4.0.11
150
+ specification_version: 4
151
+ summary: Ruby SDK for the Bayarcash payment gateway.
152
+ test_files: []