Issues (7)

src/Classes/VTPassResponse.php (1 issue)

1
<?php
2
/**
3
 * Created By: Henry Ejemuta
4
 * Project: laravel-vtpass
5
 * Class Name: VTPassResponse.php
6
 * Date Created: 7/14/20
7
 * Time Created: 3:12 PM
8
 */
9
10
namespace HenryEjemuta\LaravelVTPass\Classes;
11
12
use HenryEjemuta\LaravelVTPass\Exceptions\VTPassErrorException;
13
14
/**
15
 * The VTPassResponse Class parse all response from the VTPass RESTful API and present a standard and convenient way of
16
 * accessing response status as well as related error which are throwable through the VTPassErrorException class.
17
 * The response messages are determined from the status code as documented https://www.vtpass.com/documentation/response-codes/
18
 *
19
 * Your query response body is accessible via the $vtPassCall->getBody(); where $vtPassCall is the instance of the VTPassResponse
20
 * response class return from any of the API call
21
 *
22
 * @package HenryEjemuta\LaravelVTPass\Classes
23
 */
24
class VTPassResponse
25
{
26
    private const RESPONSE = [
27
        "000" => ['error' => false, 'title' => 'TRANSACTION PROCESSED', 'message' => 'Transaction is processed. Please check [content][transactions][status] for the status of the transaction. It would contain the actual state like initiated, pending, delivered, reversed, resolved. See the next table for more information.'],
28
        "099" => ['error' => false, 'title' => 'TRANSACTION IS PROCESSING', 'message' => 'Transaction is currently precessing. In such situation, you should requery using your requestID to ascertain the current status of the transaction.'],
29
        "016" => ['error' => true, 'title' => 'TRANSACTION FAILED', 'message' => 'TRANSACTION FAILED'],
30
        "001" => ['error' => false, 'title' => 'TRANSACTION QUERY', 'message' => 'The current status of a given transaction carried out on the platform'],
31
        "010" => ['error' => true, 'title' => 'VARIATION CODE DOES NOT EXIST', 'message' => 'You are using an invalid variation code. Please check the list of available variation codes here.'],
32
        "011" => ['error' => true, 'title' => 'INVALID ARGUMENTS', 'message' => 'You are not passing at least one of the arguments expected in your request.'],
33
        "012" => ['error' => true, 'title' => 'PRODUCT DOES NOT EXIST', 'message' => 'PRODUCT DOES NOT EXIST'],
34
        "013" => ['error' => true, 'title' => 'BELOW MINIMUM AMOUNT ALLOWED', 'message' => 'You are attempting to pay an amount lower than the minimum allowed for that product/service.'],
35
        "014" => ['error' => true, 'title' => 'REQUEST ID ALREADY EXIST', 'message' => 'You have used the RequestID for a previous transaction.'],
36
        "015" => ['error' => true, 'title' => 'INVALID REQUEST ID', 'message' => 'This is returned for a requery operation. This RequestID was not used on our platform.'],
37
        "017" => ['error' => true, 'title' => 'ABOVE MAXIMUM AMOUNT ALLOWED', 'message' => 'You are attempting to pay an amount higher than the maximum allowed for that product/service.'],
38
        "018" => ['error' => true, 'title' => 'LOW WALLET BALANCE', 'message' => 'You do not have adequate funds in your wallet to cover the cost of the transaction.'],
39
        "019" => ['error' => true, 'title' => 'LIKELY DUPLICATE TRANSACTION', 'message' => 'You attempted to buy the same service multiple times for the same biller_code within 30 seconds.'],
40
        "020" => ['error' => false, 'title' => 'BILLER CONFIRMED', 'message' => 'BILLER CONFIRMED'],
41
        "021" => ['error' => true, 'title' => 'ACCOUNT LOCKED', 'message' => 'Your account is locked'],
42
        "022" => ['error' => true, 'title' => 'ACCOUNT SUSPENDED', 'message' => 'Your account is suspended'],
43
        "023" => ['error' => true, 'title' => 'API ACCESS NOT ENABLE FOR USER', 'message' => 'Your account does not have API access enabled. Please contact us to request for activation'],
44
        "024" => ['error' => true, 'title' => 'ACCOUNT INACTIVE', 'message' => 'Your account is inactive.'],
45
        "025" => ['error' => true, 'title' => 'RECIPIENT BANK INVALID', 'message' => 'Your bank code for bank transfer is invalid.'],
46
        "026" => ['error' => true, 'title' => 'RECIPIENT ACCOUNT COULD NOT BE VERIFIED', 'message' => 'Your bank account number could not be verified.'],
47
        "027" => ['error' => true, 'title' => 'IP NOT WHITELISTED, CONTACT SUPPORT', 'message' => 'You need to contact support with your server IP for whitelisting'],
48
        "030" => ['error' => true, 'title' => 'BILLER NOT REACHABLE AT THIS POINT', 'message' => 'The biller for the product or service is unreachable.'],
49
        "031" => ['error' => true, 'title' => 'BELOW MINIMUM QUANTITY ALLOWED', 'message' => 'You are under-requesting for a service that has a limit on the quantity to be purchased per time.'],
50
        "032" => ['error' => true, 'title' => 'ABOVE MINIMUM QUANTITY ALLOWED', 'message' => 'You are over-requesting for a service that has a limit on the quantity to be purchased per time.'],
51
        "034" => ['error' => true, 'title' => 'SERVICE SUSPENDED', 'message' => 'The service being requested for has been suspended for the time being.'],
52
        "035" => ['error' => true, 'title' => 'SERVICE INACTIVE', 'message' => 'You are requesting for a service that has been turned off at the moment.'],
53
        "040" => ['error' => true, 'title' => 'TRANSACTION REVERSAL', 'message' => 'Transaction reversal to wallet'],
54
        "083" => ['error' => true, 'title' => 'SYSTEM ERROR', 'message' => 'Oops!!! System error. Please contact tech support'],
55
    ];
56
57
58
    private const TRANSACTION_PROCESSED_STATUS = [
59
        "initiated" => ['meaning' => 'Transaction has been initiated', 'note' => 'Transaction is initiated.'],
60
        "pending" => ['meaning' => 'Transaction is pending', 'note' => 'Transaction is pending. This may happen when service provider has not concluded the transaction. This status will be updated. Please requery to get a final status.'],
61
        "delivered" => ['meaning' => 'Transaction Successful', 'note' => 'Transaction is successful and service is confirmed as delivered.'],
62
        "reversed" => ['meaning' => 'Transaction Reversed', 'note' => 'Payment reversed to your wallet.'],
63
        "resolved" => ['meaning' => 'Transaction has been Resolved', 'note' => 'Please contact us for more information.']
64
    ];
65
    /**
66
     * @var bool
67
     */
68
    private $hasError;
69
70
    /**
71
     * @var string $title
72
     */
73
    private $title;
74
75
    /**
76
     * Response Message as determined by status code
77
     * @var string $message
78
     */
79
    private $message;
80
81
    /**
82
     * Response Body from
83
     * @var object|null $body
84
     */
85
    private $body;
86
87
    /**
88
     * @var array $additionalStatusDetails
89
     */
90
    private $additionalStatus;
91
92
    /**
93
     * VTPassResponse constructor.
94
     * @param string $code
95
     * @param object|array|null $responseBody
96
     * @throws VTPassErrorException
97
     */
98
    public function __construct(string $code, $responseBody = null)
99
    {
100
        $this->body = $responseBody;
0 ignored issues
show
Documentation Bug introduced by
It seems like $responseBody can also be of type array. However, the property $body is declared as type null|object. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
101
        $this->additionalStatus = [];
102
        $this->title = "Empty Response";
103
        $this->message = "Empty Response from VTPass server";
104
        $this->hasError = false;
105
106
        if (isset(VTPassResponse::RESPONSE["$code"])) {
107
            $msg = VTPassResponse::RESPONSE["$code"];
108
            $this->title = $msg['title'];
109
            $this->message = $msg['message'];
110
            $this->hasError = $msg['error'];
111
            if ("$code" === "000" && isset($responseBody->status)) {
112
                if (isset(VTPassResponse::TRANSACTION_PROCESSED_STATUS["{$responseBody->status}"])) {
113
                    $this->additionalStatus = VTPassResponse::TRANSACTION_PROCESSED_STATUS["{$responseBody->status}"];
114
                }
115
            }
116
        }
117
118
        if ($this->hasError)
119
            throw new VTPassErrorException($this->message, "$code");
120
121
    }
122
123
    /**
124
     * Determine if this ise a success response object
125
     * @return bool
126
     */
127
    public function successful(): bool
128
    {
129
        return !($this->hasError);
130
    }
131
132
    /**
133
     * @return string
134
     */
135
    public function getTitle(): string
136
    {
137
        return $this->title;
138
    }
139
140
    /**
141
     * @return string
142
     */
143
    public function getMessage(): string
144
    {
145
        return $this->message;
146
    }
147
148
    /**
149
     * @return object|array|null
150
     */
151
    public function getBody()
152
    {
153
        return $this->body;
154
    }
155
156
    /**
157
     * @return object
158
     */
159
    public function getAdditionalStatus(): object
160
    {
161
        return (object)($this->additionalStatus);
162
    }
163
164
    public function __toString()
165
    {
166
        return json_encode($this->body);
167
    }
168
169
170
}
171