Completed
Push — master ( 25ee03...611da7 )
by Leith
02:13
created

PurchaseRequest::setSecretKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Omnipay\CyberSource\Message;
4
5
use Omnipay\Common\Message\AbstractRequest;
6
7
/**
8
 * CyberSource Purchase Request
9
 */
10
class PurchaseRequest extends AbstractRequest
11
{
12
    /** @var string */
13
    protected $liveEndpoint = 'https://secureacceptance.cybersource.com/pay';
14
    /** @var string */
15
    protected $testEndpoint = 'https://testsecureacceptance.cybersource.com/pay';
16
    /** @var string  Override this if using inherited class for additional transaction types */
17
    protected $transactionType = 'sale';
18
19
    /**
20
     * Get the profile ID for the merchant account
21
     *
22
     * @return string
23
     */
24 4
    public function getProfileId()
25
    {
26 4
        return $this->getParameter('profileId');
27
    }
28
29
    /**
30
     * Set the profile ID for the merchant account
31
     *
32
     * @param string $value  ASCII Alphanumeric + punctuation string, maximum 36 characters
33
     *
34
     * @return AbstractRequest
35
     */
36 14
    public function setProfileId($value)
37
    {
38 14
        return $this->setParameter('profileId', $value);
39
    }
40
41
    /**
42
     * Get the secret key for the merchant account
43
     *
44
     * @return string
45
     */
46 8
    public function getSecretKey()
47
    {
48 8
        return $this->getParameter('secretKey');
49
    }
50
51
    /**
52
     * Set the secret key for the merchant account
53
     *
54
     * @param string $value  Alphanumeric string, maximum 32 characters
55
     *
56
     * @return AbstractRequest
57
     */
58 14
    public function setSecretKey($value)
59
    {
60 14
        return $this->setParameter('secretKey', $value);
61
    }
62
63
    /**
64
     * Get the access key for the merchant account
65
     *
66
     * @return string
67
     */
68 4
    public function getAccessKey()
69
    {
70 4
        return $this->getParameter('accessKey');
71
    }
72
73
    /**
74
     * Set the access key for the merchant account
75
     *
76
     * @param string $value  Alphanumeric string, maximum 32 characters
77
     *
78
     * @return AbstractRequest
79
     */
80 14
    public function setAccessKey($value)
81
    {
82 14
        return $this->setParameter('accessKey', $value);
83
    }
84
85
    /**
86
     * Optional merchant sale reference number, falls back to using the transaction ID if not set
87
     *
88
     * @return string
89
     */
90 3
    public function getReferenceNumber()
91
    {
92 3
        $reference = $this->getParameter('referenceNumber');
93 3
        return empty($reference) ? $this->getTransactionId() : $reference;
94
    }
95
96
    /**
97
     * Set the unique merchant-generated order reference or tracking number for each transaction.
98
     *
99
     * @param string $value  Reference to use
100
     */
101 1
    public function setReferenceNumber($value)
102
    {
103 1
        return $this->setParameter('referenceNumber', $value);
104
    }
105
106
    /**
107
     * Get the locale set for this request, falls back to using 'en' if not set
108
     *
109
     * @return string
110
     */
111 3
    public function getLocale()
112
    {
113 3
        $locale = $this->getParameter('locale');
114 3
        return empty($locale) ? 'en' : $locale;
115
    }
116
117
    /**
118
     * Set the locale for this request
119
     *
120
     * @param string  $value  ISO formatted string indicating language and country e.g. en-nz
121
     */
122 1
    public function setLocale($value)
123
    {
124 1
        return $this->setParameter('locale', $value);
125
    }
126
127
    /**
128
     * Get the transaction type
129
     *
130
     * Can be one of:
131
     *  - authorization
132
     *  - authorization,create_payment_token
133
     *  - authorization,update_payment_token
134
     *  - sale
135
     *  - sale,create_payment_token
136
     *  - sale,update_payment_token
137
     *  - create_payment_token
138
     *  - update_payment_token
139
     *
140
     * @return string
141
     */
142 2
    public function getTransactionType()
143
    {
144 2
        return $this->transactionType;
145
    }
146
147 2
    public function getData()
148
    {
149 2
        $this->validate(
150 2
            'profileId',
151 2
            'accessKey',
152
            // the secret key is not supplied in the data, but is required for generating the signature
153 2
            'secretKey',
154 2
            'amount',
155 2
            'currency'
156
        );
157
158
        // mandatory fields
159
        $data = array(
160 2
            'access_key' => $this->getAccessKey(),
161 2
            'amount' => $this->getAmount(),
162
            // uses ISO-4217 codes
163 2
            'currency' => $this->getCurrency(),
164 2
            'locale' => $this->getLocale(),
165 2
            'profile_id' => $this->getProfileId(),
166
            // no duplicate checking on this (falls back to transaction ID if not set)
167 2
            'reference_number' => $this->getReferenceNumber(),
168
            // ISO 8601 date in UTC
169 2
            'signed_date_time' => gmdate("Y-m-d\TH:i:s\Z"),
170 2
            'transaction_type' => $this->getTransactionType(),
171
            // merchant-generated transaction number used for duplicate checking
172 2
            'transaction_uuid' => $this->getTransactionId(),
173
        );
174
175
        // optional fields
176
        $optional_data = array(
177 2
            'customer_ip_address' => $this->getClientIp(),
178
            // merchant defined data 1-4 are stored with tokens, so transaction-specific data from 5 onwards
179 2
            'merchant_defined_data5' => $this->getDescription(),
180 2
            'override_backoffice_post_url' => $this->getNotifyUrl(),
181 2
            'override_custom_cancel_page' => $this->getCancelUrl(),
182
            // signing this field is actually required if present, despite what the integration docs say
183 2
            'override_custom_receipt_page' => $this->getReturnUrl(),
184
        );
185
186
        // billing details
187 2
        $card = $this->getCard();
188 2
        if ($card) {
189
            $optional_data += array(
190 1
                'bill_to_forename' => $card->getFirstName(),
191 1
                'bill_to_surname' => $card->getLastName(),
192 1
                'bill_to_address_line1' => $card->getAddress1(),
193 1
                'bill_to_address_line2' => $card->getAddress2(),
194 1
                'bill_to_address_city' => $card->getCity(),
195
                //alphanumeric,2 [ISO state code; req for US/CA]
196
                // @todo should this kind of reformatting (or error) happen in driver, or at merchant end?
197 1
                'bill_to_address_state' => $card->getState(),
198
                // alphanumeric,10 [strict format check for US/CA addresses]
199
                // @todo should this kind of reformatting (or error) happen in driver, or at merchant end?
200 1
                'bill_to_address_postal_code' => $card->getPostcode(),
201 1
                'bill_to_address_country' => $card->getCountry(),
202 1
                'bill_to_email' => $card->getEmail(),
203 1
                'bill_to_phone' => $card->getPhone(),
204
            );
205
        }
206
207
        // item details
208 2
        $items = $this->getItems();
209 2
        if ($items) {
210
            // having any item details forces line_item_count to be required
211
            $optional_data += array(
212 1
                'line_item_count' => count($items),
213
            );
214 1
            foreach ($items as $n => $item) {
215
                $optional_data += array(
216 1
                    "item_{$n}_name" => $item->getName(),
217 1
                    "item_{$n}_quantity" => $item->getQuantity(),
218 1
                    "item_{$n}_unit_price" => $this->formatCurrency($item->getPrice()),
219
                );
220
                // @todo if we want to add additional fields, need to create CyberSourceItem and CyberSourceItemBag
221
                // if ($item instanceof CyberSourceItem) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
222
                //     "item_{$n}_code" => $item->getCode(),
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
223
                //     "item_{$n}_sku" => $item->getSku(),
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
224
                //     "item_{$n}_tax_amount" => $this->formatCurrency($item->getTax()),
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
225
                // }
226
            }
227
        }
228
229
        // omit any optional parameters that aren't set
230 2
        $optional_data = array_filter($optional_data);
231
        // merge data
232 2
        $data += $optional_data;
233
234
        // rather than working out peculiar loopholes in the integration documentation, just sign everything
235 2
        $data['unsigned_field_names'] = '';
236 2
        $data['signed_field_names'] = implode(',', array_keys($data)).',signed_field_names';
237
238 2
        return $data;
239
    }
240
241 1
    public function sendData($data)
242
    {
243 1
        $security = new Security();
244 1
        $data['signature'] = $security->createSignature(
245 1
            $data,
246 1
            explode(',', $data['signed_field_names']),
247 1
            $this->getSecretKey()
248
        );
249 1
        return $this->response = new PurchaseResponse($this, $data);
250
    }
251
252 2
    public function getEndpoint()
253
    {
254 2
        return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
255
    }
256
}
257