Show last authors
1 == Introduction ==
2
3 PayEx Checkout v1 is an easy way for customers to complete payments. We provide a two-phase payment method which means that an amount is initially reserved (authorized), then deducted (captured) and described in more detail when you are ready to send out the goods.
4
5 == What you need before you get started ==
6
7 * HTTPS enabled web server
8 * Agreement that includes PayEx Checkout
9 * Obtained credentials (access token) from PayEx
10
11 To get a grasp of what we expect of your implementation when you are finished, we recommend that you take a peek at the following sequence diagram before you get started.
12
13
14 {{plantuml}}
15 @startuml
16 skinparam sequence{
17 ArrowColor #2DA944
18
19 ActorFontColor #333333
20 ActorFontStyle bold
21 ActorFontSize 15
22 ActorBackgroundColor #fefefe
23 ActorBorderColor #2DA944
24
25 LifeLineBorderColor #999999
26 LifeLineBackgroundColor #dddddd
27
28 ParticipantBorderColor #2DA944
29 ParticipantBackgroundColor #ffffff
30 ParticipantFontColor #333333
31 ParticipantFontStyle bold
32 }
33
34 skinparam Roundcorner 10
35 skinparam Shadowing false
36
37 skinparam ActivityBorderColor #123123
38
39 skinparam NoteBackgroundColor white
40 skinparam NoteBorderColor #999999
41 skinparam NoteFontColor #333333
42
43 skinparam sequenceDividerBackgroundColor white
44 skinparam sequenceDividerBorderColor #999999
45 skinparam sequenceDividerFontStyle bold
46 skinparam sequenceDividerFontSize 15
47
48 Actor Consumer
49 Participant "Merchant Web Page" as MerchantWebPage
50 Participant "Merchant Web Server" as MerchantWebServer
51 Participant PayEx
52 '//Sequence start//'
53
54 Consumer->MerchantWebPage: Open page with Checkout button
55 Activate MerchantWebPage
56 MerchantWebPage->MerchantWebServer: Load web page
57 Activate MerchantWebServer
58 ==[[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/#HStep1:Createpaymentsession step 1: create payment session ]]==
59 MerchantWebServer->PayEx: GET [[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/Testdata/#HUsefulURLs <checkout baseUrl>]]
60 Activate PayEx
61 note left: First API request
62 MerchantWebServer<--PayEx: Response: {paymentSessionUrl}
63 MerchantWebServer->PayEx: POST [[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/Introduction/Payment-session/ <checkout paymentSessionUrl> $accessToken]]
64 note left: Second API request
65 PayEx-->MerchantWebServer: {paymentSessionUrl}
66 Deactivate PayEx
67 MerchantWebServer->MerchantWebServer: Save {paymentSessionUrl} to local storage
68
69 MerchantWebServer->MerchantWebPage: Page with Checkout config {paymentSessionUrl}
70 Deactivate MerchantWebServer
71 ==[[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/#HStep2:Configureyourfrontend step 2: configure your frontend]]==
72
73 MerchantWebPage->PayEx: GET checkout.js
74 Activate PayEx
75 PayEx->MerchantWebPage: Serve static JavaScript
76 Deactivate PayEx
77 MerchantWebPage->Consumer: Show purchase page
78 Deactivate MerchantWebPage
79 |||
80 hnote over MerchantWebPage: Consumer presses Checkout button
81
82 Consumer->MerchantWebPage: Checkout button clicked
83
84
85 ==[[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/#HStep3:Paymentwindow step 3: payment window]]==
86 Activate MerchantWebPage
87 MerchantWebPage->Consumer: Display Checkout to Consumer
88 note right: Checkout window opens. Consumer purchase dialogue
89 Consumer->MerchantWebPage: Enter payment data
90 MerchantWebPage->PayEx: Payment data is sent to PayEx for authorization
91 Activate PayEx
92 PayEx-->MerchantWebPage: Response purchase dialog
93 Deactivate PayEx
94 note left: Checkout windows closes
95 MerchantWebPage->MerchantWebServer: POST Payment <form>
96 Deactivate MerchantWebPage
97
98 Activate MerchantWebServer
99 ==[[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/#HStep4:Getpaymentstatus step 4: get payment status]]==
100 MerchantWebServer<-MerchantWebServer: Get {paymentSessionUrl} from storage
101
102 MerchantWebServer->PayEx: GET [[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/Introduction/Payment-session/ <paymentSessionUrl> $merchantToken]]
103 note left: Third API request
104 Activate PayEx
105 PayEx-->MerchantWebServer: Respons paymentSession Object
106
107 MerchantWebServer->PayEx: GET [[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/Introduction/Payment/ <paymentUrl> $merchantToken]]
108 note left: Fourth API request
109 MerchantWebServer<--PayEx: Response paymentStatus Object
110 Deactivate PayEx
111
112 MerchantWebServer<-MerchantWebServer: Save paymentStatusObject
113 MerchantWebServer->MerchantWebPage:Receipt page
114 Deactivate MerchantWebPage
115 Deactivate MerchantWebServer
116
117 |||
118 hnote over MerchantWebServer: Awaiting order fullfilment
119 |||
120
121 ==[[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/#HStep5:Capturethepayment step 5: capture the payment]]==
122
123 MerchantWebServer->MerchantWebServer: Complete order
124 Activate MerchantWebServer
125 MerchantWebServer->PayEx: POST [[https://wiki.payex.com/xwiki/wiki/developer/view/Main/ECommerce/PayEx%20Checkout/Introduction/Payment/#HCapture <CaptureUrl> $merchantToken]]
126 Activate PayEx
127 note left: Fifth API request
128 PayEx-->MerchantWebServer: Capture response
129 Deactivate PayEx
130 MerchantWebServer->MerchantWebServer: Ship goods
131 MerchantWebServer->Consumer: Consumer recieves goods
132 Deactivate MerchantWebServer
133 '//Sequence end//'
134 @enduml
135 {{/plantuml}}
136
137
138
139 == What you should do, step by step ==
140
141 Below is an example implementation provided in C# 6, .NET 4.5.1+ and Newtonsoft.Json for the backend code. The frontend naturally uses HTML5 and JavaScript. To view backend examples of the raw HTTP request and response messages, please have a look at the [[Backend API documentation>>doc:Sandbox.payex-checkout-v1.Introduction.WebHome]].
142
143 Note that the examples are written for a "happy path" implementation and thus contain no error handling of any kind. The examples are therefore not production ready code to be used in an actual application, they are just provided to help understanding the API and give the implementation a head start.
144
145 Test data is located in the [[Test Data section>>doc:Sandbox.payex-checkout-v1.Testdata.WebHome]]. If you encounter any problem with the implementation, please visit the troubleshooting section or [[send us an e-mail>>mailto:support.ecom@payex.com]].
146
147 === Step 1: Create payment session ===
148
149 Create a payment session by doing a HTTP POST from your webserver with payment info and your merchant token. The response from the POST will contain a Payment Session URL that you will need later. Save this value for future use (frontend config and operations on the payment) related to the order/shoppingcart in your database.
150
151 {{tabs idsToLabels="HTTP=HTTP, CS=C#"/}}
152
153 (% id="HTTP" %)
154 (((
155 Retrieve the Home resource and locate the Payment Session base URL
156
157 **Request**
158
159 {{code language="JavaScript"}}
160 GET https://api.payex.com/psp/checkout/ HTTP/1.1
161 Accept: application/json
162 Authorization: Bearer merchantToken==
163 {{/code}}
164
165 **Response**
166
167 {{code language="JavaScript"}}
168 HTTP/1.1 200 OK
169 Content-Type: application/json
170
171 {
172 "paymentSession": "<payment_session_url>"
173 }
174 {{/code}}
175
176 Perform the POST request to the Payment Session base URL to create a Payment Session
177
178 **Request**
179
180 {{code language="JavaScript"}}
181 POST https://api.payex.com/psp/checkout/payment-sessions/ HTTP/1.1
182 Content-Type: application/json
183 Authorization: Bearer merchantToken==
184
185 {
186 "amount": 199.50,
187 "vatAmount": 39.90,
188 "currency": "NOK",
189 "callbackUrl": "https://merchant.api/callback",
190 "reference": "merchant-order-123",
191 "acquire": ["email", "mobilePhoneNumber", "shippingAddress"],
192 "culture": "nb-NO",
193 "hosts": ["https://merchant.com/"],
194 "payer": {
195 "email": "payer@example.com",
196 "mobilePhoneNumber": "+4712345678"
197 },
198 "fees" : {
199 "invoice": {
200 "amount": 19.50,
201 "vatAmount": 3.90,
202 "description": "Invoice fee"
203 }
204 }
205 }
206
207 {{/code}}
208
209 **Response**
210
211 {{code language="JavaScript"}}
212 HTTP/1.1 201 Created
213 Content-Type: application/json
214 Location: https://api.payex.com/psp/checkout/payment-sessions/123-456-789
215
216 {
217 "id": "https://api.payex.com/psp/checkout/payment-sessions/123-456-789",
218 "amount": 199.50,
219 "vatAmount": 39.90,
220 "currency": "NOK",
221 "callbackUrl": "https://merchant.api/callback",
222 "reference": "merchant-order-123",
223 "acquire": ["email", "mobilePhoneNumber", "shippingAddress"],
224 "culture": "nb-NO",
225 "hosts": ["https://merchant.com/"],
226 "payer": {
227 "email": "payer@example.com",
228 "mobilePhoneNumber": "+4712345678"
229 },
230 "fees" : {
231 "invoice": {
232 "amount": 19.50,
233 "vatAmount": 3.90,
234 "description": "Invoice fee"
235 }
236 }
237 }
238 {{/code}}
239
240 Find the URL of the created Payment Session in the HTTP 'Location' header and store it alongside the order, shopping cart, or similar
241 )))
242
243 (% id="CS" %)
244 (((
245 {{code language="c#"}}
246 var merchantToken = "<secret merchant token>";
247 var httpClient = new HttpClient();
248 httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + merchantToken);
249
250 // 1. Retrieve the Home resource and locate the Payment Session base URL.
251 var homeResponse = await httpClient.GetAsync("https://api.payex.com/psp/checkout");
252 var homeContent = await homeResponse.Content.ReadAsStringAsync();
253 var home = Newtonsoft.Json.Linq.JObject.Parse(homeContent);
254 var paymentSessionBaseUrl = home["paymentSession"].ToString();
255
256 // 2. Perform the POST request to the Payment Session base URL to create a Payment Session
257 var json = Newtonsoft.Json.JsonConvert.SerializeObject(new
258 {
259 amount = 100.00,
260 vatAmount = 20.00,
261 currency = "NOK",
262 callbackUrl = "https://merchant.api/callback",
263 reference = "merchant-order-123",
264 acquire = new[] { "shippingAddress" },
265 culture = "nb-NO"
266 });
267 var paymentSessionContent = new StringContent(json, Encoding.UTF8, "application/json");
268 var paymentSessionResponse = await httpClient.PostAsync(paymentSessionBaseUrl, paymentSessionContent);
269
270 // 3. Find the URL of the created Payment Session in the HTTP 'Location' header and store it alongside the order, shopping cart, or similar.
271 var paymentSessionUrl = paymentSessionResponse.Headers.Location;
272 {{/code}}
273
274 After the above code is executed, the {{code}}paymentSessionUrl{{/code}} variable will contain the URL to a Payment Session that contains the payment data used to guide the user through the PayEx Checkout user flow. **Remember to persist the {{code}}paymentSessionUrl{{/code}} to storage** related to the order, shopping cart or similar represented by the {{code}}reference{{/code}} above.
275 )))
276
277 ----
278
279 Your can read more about the payment session object [[here>>Sandbox.payex-checkout-v1.Introduction.Payment-session.WebHome]].
280
281 === Step 2: Configure your frontend ===
282
283 PayEx Checkout uses a script that bootstraps the payment process when your purchase button is clicked. Add the PayEx Checkout script to your page:
284
285 {{code language="html"}}
286 <script src="https://checkout.externalintegration.payex.com/js/payex-checkout.min.js"></script>
287 {{/code}}
288
289 Please note that the above URL points to **PayEx Checkout's test environment**. For the URL to PayEx' production environment, [[please refer to the general API introduction>>doc:Main.ecommerce.technical-reference.card-payments.WebHome]].
290
291 Choose the button that you want to start the checkout process with and add the attribute data-payex-checkout with the value returned from return in the initial POST. Then add the disable attribute - the PayEx Checkout JavaScript will enable it when it is properly loaded. The button should be wrapped inside a form that POST to your server.
292
293 {{code language="html"}}
294 <form action="<url_to_your_server>" method="post">
295 <!-- ... -->
296 <button data-payex-checkout="<payment_session_url>" disabled>Pay</button>
297 </form>
298 {{/code}}
299
300 The PayEx Checkout script will post the form when the payment process is complete.
301
302 You can read more about how to implement PayEx Checkout in your frontend [[here>>Sandbox.payex-checkout-v1.Frontend API.WebHome]].
303
304 === Step 3: Payment window (facilitated by PayEx) ===
305
306 When a consumer clicks on the Pay button the PayEx Checkout payment window appears in the web browser. This payment window includes the following steps.
307
308 ==== Login ====
309
310 PayEx holds all payer information for easier payment procedure. If the user submits an email address a lookup process begins.
311 Otherwise an anonymous payment process is used where only credit card is available as payment method.
312
313 ==== Authentication ====
314
315 By specifying mobile phone number, a verification code is sent to your phone.
316
317 ==== Delivery ====
318
319 Depending on the parameters provided in the acquires property, various address information is required to continue to next step.
320
321 ==== Payment ====
322
323 Depending on merchant country, merchant contract and consumer country a list of payment options is displayed.
324 Possible options are currently credit card and invoice.
325 Credit card offers the option to add a new card or pick a previous card.
326 Invoice is only available for consumers in same country as merchant.
327
328 Once the payment is authorized at our end - the PayEx Checkout Javascript will post the form.
329 From the payment window is opened until it closes, everything in the payment process is performed entirely by PayEx. After that we expect a receipt to be sent to the consumer.
330
331 === Step 4: Get payment status ===
332
333 After a successfully authorized payment, the purchase form will be submitted as earlier mentioned. It is assumed that the form contains the reference connecting the previously persisted {{code}}paymentSessionUrl{{/code}} to the order, shopping cart, or similar.
334
335 When the form is submitted, look up the {{code}}paymentSesionUrl{{/code}} and perform a {{code}}GET{{/code}} request on it to retrieve the status of the payment. The returned JSON will also contain the necessary URLs to perform actions on the payment such as capture, cancel and reversal.
336
337 {{tabs idsToLabels="HTTP_2=HTTP, C_2=C#"/}}
338
339 (% id="HTTP_2" %)
340 (((
341 Retrieve the ##paymentSessionUrl## related to the submitted form from storage, and then retrieve the Payment Session and find the URL of the Payment.
342
343 **Request**
344
345 {{code language="JavaScript"}}
346 GET https://api.payex.com/psp/checkout/payment-sessions/123-456-789 HTTP/1.1
347 Accept: application/json
348 Authorization: Bearer merchantToken==
349 {{/code}}
350
351 **Response**
352
353 {{code language="JavaScript"}}
354 HTTP/1.1 200 OK
355 Content-Type: application/json
356
357 {
358 "amount": 199.50,
359 "vatAmount": 39.90,
360 "currency": "NOK",
361 "callbackUrl": "https://merchant.api/callback",
362 "reference": "merchant-order-123",
363 "acquire": ["email", "mobilePhoneNumber", "shippingAddress"],
364 "culture": "nb-NO",
365 "addressee": {
366 "name": "Olivia Nyhuus",
367 "email": "olivia.nyhuus@example.com",
368 "mobilePhoneNumber": "004791234567",
369 "shippingAddress": {
370 "city": "Oslo",
371 "countryCode": "NO",
372 "streetAddress": "StÄlverkskroken, 4",
373 "zipCode": "0661"
374 }
375 },
376 "payment": "https://api.payex.com/psp/payment/credit-card/984-223-836",
377 }
378 {{/code}}
379
380 Retrieve the Payment and inspect its state.
381
382 **Request**
383
384 {{code language="JavaScript"}}
385 GET <payment_url> HTTP/1.1
386 Content-Type: application/json
387 Authorization: Bearer merchantToken==
388 {{/code}}
389
390 **Response**
391
392 {{code language="JavaScript"}}
393 {
394 "payment": {
395 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c",
396 "number": 1234567890,
397 "created": "2016-09-14T13:21:29.3182115Z",
398 "updated": "2016-09-14T13:21:57.6627579Z",
399 "operation": "Purchase|Verify|Recur",
400 "intent": "Authorization|AutoCapture",
401 "state": "Ready|Pending|Failed|Aborted",
402 "currency": "NOK|SEK|...",
403 "amount": 1500,
404 "remainingCaptureAmount": 1500,
405 "remainingCancellationAmount": 1500,
406 "remainingReversalAmount": 0,
407 "description": "Test Purchase",
408 "initiatingSystemUserAgent": "PostmanRuntime/3.0.1",
409 "userAgent": "Mozilla/5.0...",
410 "language": "nb-NO",
411 "paymentToken": "5adc265f-f87f-4313-577e-08d3dca1a26c",
412 "prices": {
413 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/prices"
414 },
415 "transactions": {
416 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/transactions"
417 },
418 "authorizations": {
419 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/authorizations"
420 },
421 "captures": {
422 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/captures"
423 },
424 "cancellations": {
425 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/cancellations"
426 },
427 "reversals": {
428 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/reversals"
429 },
430 "payeeInfo": {
431 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/payeeInfo"
432 },
433 "urls": {
434 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/urls"
435 },
436 "settings": {
437 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/settings"
438 }
439 },
440 "operations": [
441 {
442 "href": "<capture_operation_url>",
443 "rel": "create-checkout-capture",
444 "method": "POST"
445 },
446 {
447 "href": "<cancellation_operation_url>",
448 "rel": "create-checkout-cancellation",
449 "method": "POST"
450 },
451 {
452 "href": "<reversal_operation_url>",
453 "rel": "create-checkout-reversal",
454 "method": "POST"
455 }
456 ]
457 }
458 {{/code}}
459 )))
460
461 (% id="C_2" %)
462 (((
463 ===== Implementation example =====
464
465 {{code language="c#"}}
466 var merchantToken = "<secret merchant token>";
467 var httpClient = new HttpClient();
468 httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + merchantToken);
469
470 // 1. Retrieve the paymentSessionUrl related to the submitted form from storage.
471 var paymentSessionUrl = "<retrieved from storage>";
472
473 // 2. Retrieve the Payment Session and find the URL of the Payment.
474 var paymentSessionResponse = await httpClient.GetAsync(paymentSessionUrl);
475 var paymentSessionContent = await paymentSessionResponse.Content.ReadAsStringAsync();
476 var paymentSession = Newtonsoft.Json.Linq.JObject.Parse(paymentSessionContent);
477 var paymentUrl = paymentSession["payment"].ToString();
478
479 // 3. Retrieve the Payment and inspect its state.
480 var paymentResponse = await httpClient.GetAsync(paymentUrl);
481 var paymentContent = await paymentResponse.Content.ReadAsStringAsync();
482 var payment = Newtonsoft.Json.Linq.JObject.Parse(paymentContent);
483 var paymentState = payment["state"].ToString();
484 {{/code}}
485
486 After the above code example is executed, the {{code}}paymentState{{/code}} variable will contain the value {{code}}Ready{{/code}}, {{code}}Pending{{/code}}, {{code}}Failed{{/code}} or {{code}}Aborted{{/code}}. Use it to provide a message to the user in the form of a receipt, an error message in the event of failure, etc.
487 )))
488
489 ----
490
491 In a normal flow the paymentState will be {{code}}Ready{{/code}} and it is now expected that an order confirmation is presented to the consumer in your webshop and that you ship the confirmation per email.
492
493 Read more about the payment session [[here>>Sandbox.payex-checkout-v1.Introduction.Payment-session.WebHome||anchor="HRetrievePaymentSession"]].
494
495 == Step 5: Capture the payment ==
496
497 {{tabs idsToLabels="HTTP_3=HTTP, C_3=C#"/}}
498
499 Capture can be done at any time, depending on whether you want to physically send the purchased goods to the customer first, for instance. Just repeat the {{code}}GET{{/code}} request to the {{code}}paymentSessionUrl{{/code}}, find the {{code}}capture{{/code}} operation and execute it. We now expect an order confirmation to be sent to the consumer.
500
501
502 (% id="HTTP_3" %)
503 (((
504 Retrieve the {{code}}paymentSessionUrl{{/code}} related to the submitted form from storage, and then retrieve the Payment Session and find the URL of the Payment.
505
506 **Request**
507
508 {{code language="JavaScript"}}
509 GET https://api.payex.com/psp/checkout/payment-sessions/123-456-789 HTTP/1.1
510 Accept: application/json
511 Authorization: Bearer merchantToken==
512 {{/code}}
513
514 **Response**
515
516 {{code language="JavaScript"}}
517 HTTP/1.1 200 OK
518 Content-Type: application/json
519
520 {
521 "amount": 199.50,
522 "vatAmount": 39.90,
523 "currency": "NOK",
524 "callbackUrl": "https://merchant.api/callback",
525 "reference": "merchant-order-123",
526 "acquire": ["email", "mobilePhoneNumber", "shippingAddress"],
527 "culture": "nb-NO",
528 "addressee": {
529 "name": "Olivia Nyhuus",
530 "email": "olivia.nyhuus@example.com",
531 "mobilePhoneNumber": "004791234567",
532 "shippingAddress": {
533 "city": "Oslo",
534 "countryCode": "NO",
535 "streetAddress": "StÄlverkskroken, 4",
536 "zipCode": "0661"
537 }
538 },
539 "payment": "https://api.payex.com/psp/payment/credit-card/984-223-836"
540 }
541 {{/code}}
542
543 Retrieve the Payment and find its {{code}}create-checkout-capture{{/code}} operation:
544
545 **Request**
546
547 {{code language="JavaScript"}}
548 GET <payment_url> HTTP/1.1
549 Content-Type: application/json
550 Authorization: Bearer merchantToken==
551 {{/code}}
552
553 **Response**
554
555 {{code language="JavaScript"}}
556 {
557 "payment": {
558 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c",
559 "number": 1234567890,
560 "created": "2016-09-14T13:21:29.3182115Z",
561 "updated": "2016-09-14T13:21:57.6627579Z",
562 "operation": "Purchase|Verify|Recur",
563 "intent": "Authorization|AutoCapture",
564 "state": "Ready|Pending|Failed|Aborted",
565 "currency": "NOK|SEK|...",
566 "amount": 1500,
567 "remainingCaptureAmount": 1500,
568 "remainingCancellationAmount": 1500,
569 "remainingReversalAmount": 0,
570 "description": "Test Purchase",
571 "initiatingSystemUserAgent": "PostmanRuntime/3.0.1",
572 "userAgent": "Mozilla/5.0...",
573 "language": "nb-NO",
574 "paymentToken": "5adc265f-f87f-4313-577e-08d3dca1a26c",
575 "prices": {
576 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/prices"
577 },
578 "transactions": {
579 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/transactions"
580 },
581 "authorizations": {
582 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/authorizations"
583 },
584 "captures": {
585 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/captures"
586 },
587 "cancellations": {
588 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/cancellations"
589 },
590 "reversals": {
591 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/reversals"
592 },
593 "payeeInfo": {
594 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/payeeInfo"
595 },
596 "urls": {
597 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/urls"
598 },
599 "settings": {
600 "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/settings"
601 }
602 },
603 "operations": [
604 {
605 "href": "<capture_operation_url>",
606 "rel": "create-checkout-capture",
607 "method": "POST"
608 },
609 {
610 "href": "<cancellation_operation_url>",
611 "rel": "create-checkout-cancellation",
612 "method": "POST"
613 },
614 {
615 "href": "<reversal_operation_url>",
616 "rel": "create-checkout-reversal",
617 "method": "POST"
618 }
619 ]
620 }
621 {{/code}}
622
623 Perform the capture request:
624
625 **Request**
626
627 {{code language="JavaScript"}}
628 POST <capture_operation_href> HTTP/1.1
629 Accept: application/json
630 Content-Type: application/json
631 Authorization: Bearer merchantToken==
632
633 {
634 "transaction": {
635 "description": "description for the transaction"
636 }
637 }
638 {{/code}}
639
640 **Response**
641
642 {{code language="JavaScript"}}
643 {
644 "payment": "<paymentUrl>",
645 "capture": {
646 "id": "<paymentCaptureUrl>",
647 "transaction": {
648 "id": "<transactionUrl>",
649 "created": "2016-09-14T01:01:01.01Z",
650 "updated": "2016-09-14T01:01:01.03Z",
651 "type": "Capture",
652 "state": "Initialized|Completed|Failed",
653 "number": 1234567890,
654 "amount": 1500,
655 "vatAmount": 300,
656 "description": "Test Capture",
657 "payeeReference": "ABC123",
658 "failedReason": "",
659 "isOperational": "TRUE|FALSE",
660 "operations": []
661 }
662 }
663 }
664 {{/code}}
665
666 As the {{code}}state{{/code}} property in the response above will indicate, the capture operation should now be {{code}}Completed{{/code}}, indicating that the payment is captured.
667 )))
668
669 (% id="C_3" %)
670 (((
671 Implementation example
672
673 {{code language="c#"}}
674 var merchantToken = "<secret merchant token>";
675 var httpClient = new HttpClient();
676 httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + merchantToken);
677
678 // 1. Retrieve the paymentSessionUrl related to the submitted form from storage.
679 var paymentSessionUrl = "<retrieved from storage>";
680
681 // 2. Retrieve the Payment Session and find the URL of the Payment.
682 var paymentSessionResponse = await httpClient.GetAsync(paymentSessionUrl);
683 var paymentSessionContent = await paymentSessionResponse.Content.ReadAsStringAsync();
684 var paymentSession = Newtonsoft.Json.Linq.JObject.Parse(paymentSessionContent);
685 var paymentUrl = paymentSession["payment"].ToString();
686
687 // 3. Retrieve the Payment and find its 'create-checkout-capture' operation.
688 var paymentResponse = await httpClient.GetAsync(paymentUrl);
689 var paymentContent = await paymentResponse.Content.ReadAsStringAsync();
690 var payment = Newtonsoft.Json.Linq.JObject.Parse(paymentContent);
691 var captureUrl = payment["operations"]
692 .Children()
693 .First(x => x["rel"].ToString() == "create-checkout-capture")["href"]
694 .ToString();
695
696 // 4. Perform the capture request.
697 var json = Newtonsoft.Json.JsonConvert.SerializeObject(new
698 {
699 transaction = new
700 {
701 description = "Captured the payment"
702 }
703 });
704 var captureRequestContent = new StringContent(json, Encoding.UTF8, "application/json");
705 var captureResponse = await httpClient.PostAsync(captureUrl, captureRequestContent);
706 var captureResponseContent = await captureResponse.Content.ReadAsStringAsync();
707 var capture = Newtonsoft.Json.Linq.JObject.Parse(captureResponseContent);
708 {{/code}}
709
710 When the above code example is executed, the {{code}}capture{{/code}} variable will be a JSON object containing the result of the capture operation. It is now excepted that an order receipt is sent per email to the consumer.
711
712 The above example performs a complete capture of the authorized amount. If you want to perform a more detailed captured, read more about the capture operation [[here.>>Sandbox.payex-checkout-v1.Introduction.Payment.WebHome||anchor="HCapture"]]
713 )))

Tips

Did you know that you can improve XWiki? Take 5 minutes to fill this survey and help this open source project!

Need help?

If you need help with XWiki you can contact: