From version 13.1
edited by Helge Dahl
on 2018/01/23 15:12
To version 14.1
edited by HĂ„kon Mosvoll
on 2018/01/25 10:44
Change comment: There is no comment for this version

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -xwiki:XWiki.hde
1 +xwiki:XWiki.hnm
Content
... ... @@ -1,8 +1,683 @@
1 -(% style="background-color:#A0A3A1;color:#ffffff;align=center" %)
2 -|This tencnical documentation targets technical system integrators and developers implementing PayEx Checkout.(((
3 -For technical questions, please contact [[(% style="color:#ffffff" %)PayEx Technical Support>>mailto:support.ecom@payex,com]]
1 += Introduction =
4 4  
3 +PayEx Checkout 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.
5 5  
5 += What you need before you get started =
6 6  
7 -=== (% style="color:#ffffff" %)**Get started by jumping to the [[Introduction>>doc:Main.ECommerce.PayEx Checkout.Introduction.WebHome||title="Introduction to PayEx Checkout"]] >>**(%%) ===
8 -)))|[[image:segment_checkout_w300.png]]
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://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/Implementation/#HStep1:createpaymentsession step 1: create payment session ]]==
59 +MerchantWebServer->PayEx: GET [[https://wiki.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/Home/ <checkout baseUrl>]]
60 +Activate PayEx
61 +note left: First API request
62 +MerchantWebServer<--PayEx: Response: {paymentSessionUrl}
63 +MerchantWebServer->PayEx: POST [[https://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/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://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/Implementation/#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://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/Implementation/#HStep3:paymentwindow28facilitatedbyPayEx29 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://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/Implementation/#HStep4:getpaymentstatus step 4: get payment status]]==
100 +MerchantWebServer<-MerchantWebServer: Get {paymentSessionUrl} from storage
101 +
102 +MerchantWebServer->PayEx: GET [[https://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/Payment-session/#HRetrievePaymentSession <paymentSessionUrl> $merchantToken]]
103 +note left: Third API request
104 +Activate PayEx
105 +PayEx-->MerchantWebServer: Respons paymentSession Object
106 +
107 +MerchantWebServer->PayEx: GET [[https://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/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://developer.payex.com/xwiki/wiki/external/view/ecommerce/PayEx%20Checkout/Implementation/#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/external/view/ecommerce/PayEx%20Checkout/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 +=== Implementation example ===
142 +
143 +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:Main.ECommerce.PayEx Checkout.Introduction.WebHome]].
144 +
145 +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.
146 +
147 +Testdata is located in the [[Test Data section>>doc:Main.ECommerce.PayEx Checkout.Testdata.WebHome]]. If you encounter any problem with the implementation, please visit the troubleshooting section or ask us on [[Gitter>>https://gitter.im/PayEx/PayEx.Checkout.Documentation]].
148 +
149 +== Step 1: Create payment session ==
150 +
151 +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.
152 +
153 +{{tabs idsToLabels="HTTP=HTTP, CS=C#"/}}
154 +
155 +(% id="HTTP" %)
156 +(((
157 +Retrieve the Home resource and locate the Payment Session base URL
158 +
159 +**Request**
160 +
161 +{{code language="JavaScript"}}
162 +GET https://api.payex.com/psp/checkout/ HTTP/1.1
163 +Accept: application/json
164 +Authorization: Bearer merchantToken==
165 +{{/code}}
166 +
167 +**Response**
168 +
169 +{{code language="JavaScript"}}
170 +HTTP/1.1 200 OK
171 +Content-Type: application/json
172 +
173 +{
174 + "paymentSession": "<payment_session_url>"
175 +}
176 +{{/code}}
177 +
178 +Perform the POST request to the Payment Session base URL to create a Payment Session
179 +
180 +**Request**
181 +
182 +{{code language="JavaScript"}}
183 +POST https://api.payex.com/psp/checkout/payment-sessions/ HTTP/1.1
184 +Content-Type: application/json
185 +Authorization: Bearer merchantToken==
186 +
187 +{
188 + "amount": 199.50,
189 + "vatAmount": 39.90,
190 + "currency": "NOK",
191 + "callbackUrl": "https://merchant.api/callback",
192 + "reference": "merchant-order-123",
193 + "acquire": ["email", "mobilePhoneNumber", "shippingAddress"],
194 + "culture": "nb-NO",
195 + "payer": {
196 + "email": "payer@example.com",
197 + "mobilePhoneNumber": "+4712345678"
198 + },
199 + "fees" : {
200 + "invoice": {
201 + "amount": 19.50,
202 + "vatAmount": 3.90,
203 + "description": "Invoice fee"
204 + }
205 + }
206 +}
207 +
208 +{{/code}}
209 +
210 +**Response**
211 +
212 +{{code language="JavaScript"}}
213 +HTTP/1.1 201 Created
214 +Content-Type: application/json
215 +Location: https://api.payex.com/psp/checkout/payment-sessions/123-456-789
216 +
217 +{
218 + "id": "https://api.payex.com/psp/checkout/payment-sessions/123-456-789",
219 + "payment": "<payment_url>"
220 +}
221 +{{/code}}
222 +
223 +Find the URL of the created Payment Session in the HTTP 'Location' header and store it alongside the order, shopping cart, or similar
224 +)))
225 +
226 +(% id="CS" %)
227 +(((
228 +==== Implementation example ====
229 +
230 +{{code language="c#"}}
231 +var merchantToken = "<secret merchant token>";
232 +var httpClient = new HttpClient();
233 +httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + merchantToken);
234 +
235 +// 1. Retrieve the Home resource and locate the Payment Session base URL.
236 +var homeResponse = await httpClient.GetAsync("https://api.payex.com/psp/checkout");
237 +var homeContent = await homeResponse.Content.ReadAsStringAsync();
238 +var home = Newtonsoft.Json.Linq.JObject.Parse(homeContent);
239 +var paymentSessionBaseUrl = home["paymentSession"].ToString();
240 +
241 +// 2. Perform the POST request to the Payment Session base URL to create a Payment Session
242 +var json = Newtonsoft.Json.JsonConvert.SerializeObject(new
243 +{
244 + amount = 100.00,
245 + vatAmount = 20.00,
246 + currency = "NOK",
247 + callbackUrl = "https://merchant.api/callback",
248 + reference = "merchant-order-123",
249 + acquire = new[] { "shippingAddress" },
250 + culture = "nb-NO"
251 +});
252 +var paymentSessionContent = new StringContent(json, Encoding.UTF8, "application/json");
253 +var paymentSessionResponse = await httpClient.PostAsync(paymentSessionBaseUrl, paymentSessionContent);
254 +
255 +// 3. Find the URL of the created Payment Session in the HTTP 'Location' header and store it alongside the order, shopping cart, or similar.
256 +var paymentSessionUrl = paymentSessionResponse.Headers.Location;
257 +{{/code}}
258 +
259 +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.
260 +)))
261 +
262 +----
263 +
264 +Your can read more about the payment session object [[here>>Main.ECommerce.PayEx Checkout.Introduction.Payment-session.WebHome]].
265 +
266 +== Step 2: Configure your frontend ==
267 +
268 +PayEx Checkout uses a script that bootstraps the payment process when your purchase button is clicked. Add the PayEx Checkout script to your page:
269 +
270 +{{code language="html"}}
271 +<script src="https://checkout.payex.com/js/payex-checkout.min.js"></script>
272 +{{/code}}
273 +
274 +Please note that the above URL points to **PayEx Checkout's production environment**. If you want to integrate with PayEx' test environment, [[please refer to the FAQ for the correct URLs>>doc:Main.ECommerce.PayEx Checkout.FAQ.WebHome]].
275 +
276 +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.
277 +
278 +{{code language="html"}}
279 +<form action="<url_to_your_server>" method="post">
280 + <!-- ... -->
281 + <button data-payex-checkout="<payment_session_url>" disabled>Pay</button>
282 +</form>
283 +{{/code}}
284 +
285 +The PayEx Checkout script will post the form when the payment process is complete.
286 +
287 +You can read more about how to implement PayEx Checkout in your frontend [[here>>Main.ECommerce.PayEx Checkout.Frontend API.WebHome]].
288 +
289 +== Step 3: Payment window (facilitated by PayEx) ==
290 +
291 +When consumer clicks on the Pay button the PayEx Checkout payment window appears in the web browser.
292 +Once the payment is authorized at our end - the PayEx Checkout Javascript will post the form.
293 +
294 +From the payment window opens until it closes is performed entirely by PayEx. We now expect a receipt to be sent to the consumer.
295 +
296 +== Step 4: Get payment status ==
297 +
298 +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.
299 +
300 +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.
301 +
302 +{{tabs idsToLabels="HTTP_2=HTTP, C_2=C#"/}}
303 +
304 +(% id="HTTP_2" %)
305 +(((
306 +Retrieve the paymentSessionUrl related to the submitted form from storage, and then retrieve the Payment Session and find the URL of the Payment.
307 +
308 +**Request**
309 +
310 +{{code language="JavaScript"}}
311 +GET https://api.payex.com/psp/checkout/payment-sessions/123-456-789 HTTP/1.1
312 +Accept: application/json
313 +Authorization: Bearer merchantToken==
314 +{{/code}}
315 +
316 +**Response**
317 +
318 +{{code language="JavaScript"}}
319 +HTTP/1.1 200 OK
320 +Content-Type: application/json
321 +
322 +{
323 + "amount": 199.50,
324 + "vatAmount": 39.90,
325 + "currency": "NOK",
326 + "callbackUrl": "https://merchant.api/callback",
327 + "reference": "merchant-order-123",
328 + "acquire": ["email", "mobilePhoneNumber", "shippingAddress"],
329 + "culture": "nb-NO",
330 + "addressee": {
331 + "name": "Olivia Nyhuus",
332 + "email": "olivia.nyhuus@example.com",
333 + "mobilePhoneNumber": "004791234567",
334 + "shippingAddress": {
335 + "city": "Oslo",
336 + "countryCode": "NO",
337 + "streetAddress": "StÄlverkskroken, 4",
338 + "zipCode": "0661"
339 + }
340 + },
341 + "payment": "https://api.payex.com/psp/payment/credit-card/984-223-836",
342 +}
343 +{{/code}}
344 +
345 +Retrieve the Payment and inspect its state.
346 +
347 +**Request**
348 +
349 +{{code language="JavaScript"}}
350 +GET <payment_url> HTTP/1.1
351 +Content-Type: application/json
352 +Authorization: Bearer merchantToken==
353 +{{/code}}
354 +
355 +**Response**
356 +
357 +{{code language="JavaScript"}}
358 +{
359 + "payment": {
360 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c",
361 + "number": 1234567890,
362 + "created": "2016-09-14T13:21:29.3182115Z",
363 + "updated": "2016-09-14T13:21:57.6627579Z",
364 + "operation": "Purchase|Verify|Recur",
365 + "intent": "PreAuthorization|Authorization|AutoCapture",
366 + "state": "Ready|Pending|Failed|Aborted",
367 + "currency": "NOK|SEK|...",
368 + "amount": 1500,
369 + "remainingCaptureAmount": 1500,
370 + "remainingCancellationAmount": 1500,
371 + "remainingReversalAmount": 0,
372 + "description": "Test Purchase",
373 + "initiatingSystemUserAgent": "PostmanRuntime/3.0.1",
374 + "userAgent": "Mozilla/5.0...",
375 + "language": "nb-NO",
376 + "paymentToken": "5adc265f-f87f-4313-577e-08d3dca1a26c",
377 + "prices": {
378 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/prices"
379 + },
380 + "transactions": {
381 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/transactions"
382 + },
383 + "authorizations": {
384 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/authorizations"
385 + },
386 + "captures": {
387 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/captures"
388 + },
389 + "cancellations": {
390 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/cancellations"
391 + },
392 + "reversals": {
393 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/reversals"
394 + },
395 + "payeeInfo": {
396 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/payeeInfo"
397 + },
398 + "urls": {
399 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/urls"
400 + },
401 + "settings": {
402 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/settings"
403 + }
404 + },
405 + "operations": [
406 + {
407 + "href": "<capture_operation_url>",
408 + "rel": "create-checkout-capture",
409 + "method": "POST"
410 + },
411 + {
412 + "href": "<cancellation_operation_url>",
413 + "rel": "create-checkout-cancellation",
414 + "method": "POST"
415 + },
416 + {
417 + "href": "<reversal_operation_url>",
418 + "rel": "create-checkout-reversal",
419 + "method": "POST"
420 + }
421 + ]
422 +}
423 +{{/code}}
424 +)))
425 +
426 +(% id="C_2" %)
427 +(((
428 +==== Implementation example ====
429 +
430 +{{code language="c#"}}
431 +var merchantToken = "<secret merchant token>";
432 +var httpClient = new HttpClient();
433 +httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + merchantToken);
434 +
435 +// 1. Retrieve the paymentSessionUrl related to the submitted form from storage.
436 +var paymentSessionUrl = "<retrieved from storage>";
437 +
438 +// 2. Retrieve the Payment Session and find the URL of the Payment.
439 +var paymentSessionResponse = await httpClient.GetAsync(paymentSessionUrl);
440 +var paymentSessionContent = await paymentSessionResponse.Content.ReadAsStringAsync();
441 +var paymentSession = Newtonsoft.Json.Linq.JObject.Parse(paymentSessionContent);
442 +var paymentUrl = paymentSession["payment"].ToString();
443 +
444 +// 3. Retrieve the Payment and inspect its state.
445 +var paymentResponse = await httpClient.GetAsync(paymentUrl);
446 +var paymentContent = await paymentResponse.Content.ReadAsStringAsync();
447 +var payment = Newtonsoft.Json.Linq.JObject.Parse(paymentContent);
448 +var paymentState = payment["state"].ToString();
449 +{{/code}}
450 +
451 +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.
452 +)))
453 +
454 +----
455 +
456 +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.
457 +
458 +Read more about the payment session [[here>>Main.ECommerce.PayEx Checkout.Introduction.Payment-session.WebHome||anchor="HRetrievePaymentSession"]].
459 +
460 +== Step 5: Capture the payment ==
461 +
462 +{{tabs idsToLabels="HTTP_3=HTTP, C_3=C#"/}}
463 +
464 +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.
465 +
466 +
467 +(% id="HTTP_3" %)
468 +(((
469 +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.
470 +
471 +**Request**
472 +
473 +{{code language="JavaScript"}}
474 +GET https://api.payex.com/psp/checkout/payment-sessions/123-456-789 HTTP/1.1
475 +Accept: application/json
476 +Authorization: Bearer merchantToken==
477 +{{/code}}
478 +
479 +**Response**
480 +
481 +{{code language="JavaScript"}}
482 +HTTP/1.1 200 OK
483 +Content-Type: application/json
484 +
485 +{
486 + "amount": 199.50,
487 + "vatAmount": 39.90,
488 + "currency": "NOK",
489 + "callbackUrl": "https://merchant.api/callback",
490 + "reference": "merchant-order-123",
491 + "acquire": ["email", "mobilePhoneNumber", "shippingAddress"],
492 + "culture": "nb-NO",
493 + "addressee": {
494 + "name": "Olivia Nyhuus",
495 + "email": "olivia.nyhuus@example.com",
496 + "mobilePhoneNumber": "004791234567",
497 + "shippingAddress": {
498 + "city": "Oslo",
499 + "countryCode": "NO",
500 + "streetAddress": "StÄlverkskroken, 4",
501 + "zipCode": "0661"
502 + }
503 + },
504 + "payment": "https://api.payex.com/psp/payment/credit-card/984-223-836"
505 +}
506 +{{/code}}
507 +
508 +Retrieve the Payment and find its {{code}}create-checkout-capture{{/code}} operation:
509 +
510 +**Request**
511 +
512 +{{code language="JavaScript"}}
513 +GET <payment_url> HTTP/1.1
514 +Content-Type: application/json
515 +Authorization: Bearer merchantToken==
516 +{{/code}}
517 +
518 +**Response**
519 +
520 +{{code language="JavaScript"}}
521 +{
522 + "payment": {
523 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c",
524 + "number": 1234567890,
525 + "created": "2016-09-14T13:21:29.3182115Z",
526 + "updated": "2016-09-14T13:21:57.6627579Z",
527 + "operation": "Purchase|Verify|Recur",
528 + "intent": "PreAuthorization|Authorization|AutoCapture",
529 + "state": "Ready|Pending|Failed|Aborted",
530 + "currency": "NOK|SEK|...",
531 + "amount": 1500,
532 + "remainingCaptureAmount": 1500,
533 + "remainingCancellationAmount": 1500,
534 + "remainingReversalAmount": 0,
535 + "description": "Test Purchase",
536 + "initiatingSystemUserAgent": "PostmanRuntime/3.0.1",
537 + "userAgent": "Mozilla/5.0...",
538 + "language": "nb-NO",
539 + "paymentToken": "5adc265f-f87f-4313-577e-08d3dca1a26c",
540 + "prices": {
541 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/prices"
542 + },
543 + "transactions": {
544 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/transactions"
545 + },
546 + "authorizations": {
547 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/authorizations"
548 + },
549 + "captures": {
550 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/captures"
551 + },
552 + "cancellations": {
553 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/cancellations"
554 + },
555 + "reversals": {
556 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/reversals"
557 + },
558 + "payeeInfo": {
559 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/payeeInfo"
560 + },
561 + "urls": {
562 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/urls"
563 + },
564 + "settings": {
565 + "id": "/psp/creditcard/payments/5adc265f-f87f-4313-577e-08d3dca1a26c/settings"
566 + }
567 + },
568 + "operations": [
569 + {
570 + "href": "<capture_operation_url>",
571 + "rel": "create-checkout-capture",
572 + "method": "POST"
573 + },
574 + {
575 + "href": "<cancellation_operation_url>",
576 + "rel": "create-checkout-cancellation",
577 + "method": "POST"
578 + },
579 + {
580 + "href": "<reversal_operation_url>",
581 + "rel": "create-checkout-reversal",
582 + "method": "POST"
583 + }
584 + ]
585 +}
586 +{{/code}}
587 +
588 +Perform the capture request:
589 +
590 +**Request**
591 +
592 +{{code language="JavaScript"}}
593 +POST <capture_operation_href> HTTP/1.1
594 +Accept: application/json
595 +Content-Type: application/json
596 +Authorization: Bearer merchantToken==
597 +
598 +{
599 + "transaction": {
600 + "description": "description for the transaction"
601 + }
602 +}
603 +{{/code}}
604 +
605 +**Response**
606 +
607 +{{code language="JavaScript"}}
608 +{
609 + "payment": "<paymentUrl>",
610 + "capture": {
611 + "id": "<paymentCaptureUrl>",
612 + "transaction": {
613 + "id": "<transactionUrl>",
614 + "created": "2016-09-14T01:01:01.01Z",
615 + "updated": "2016-09-14T01:01:01.03Z",
616 + "type": "Capture",
617 + "state": "Initialized|Completed|Failed",
618 + "number": 1234567890,
619 + "amount": 1500,
620 + "vatAmount": 300,
621 + "description": "Test Capture",
622 + "payeeReference": "ABC123",
623 + "failedReason": "",
624 + "isOperational": "TRUE|FALSE",
625 + "operations": []
626 + }
627 + }
628 +}
629 +{{/code}}
630 +
631 +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.
632 +)))
633 +
634 +(% id="C_3" %)
635 +(((
636 +Implementation example
637 +
638 +{{code language="c#"}}
639 +var merchantToken = "<secret merchant token>";
640 +var httpClient = new HttpClient();
641 +httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + merchantToken);
642 +
643 +// 1. Retrieve the paymentSessionUrl related to the submitted form from storage.
644 +var paymentSessionUrl = "<retrieved from storage>";
645 +
646 +// 2. Retrieve the Payment Session and find the URL of the Payment.
647 +var paymentSessionResponse = await httpClient.GetAsync(paymentSessionUrl);
648 +var paymentSessionContent = await paymentSessionResponse.Content.ReadAsStringAsync();
649 +var paymentSession = Newtonsoft.Json.Linq.JObject.Parse(paymentSessionContent);
650 +var paymentUrl = paymentSession["payment"].ToString();
651 +
652 +// 3. Retrieve the Payment and find its 'create-checkout-capture' operation.
653 +var paymentResponse = await httpClient.GetAsync(paymentUrl);
654 +var paymentContent = await paymentResponse.Content.ReadAsStringAsync();
655 +var payment = Newtonsoft.Json.Linq.JObject.Parse(paymentContent);
656 +var captureUrl = payment["operations"]
657 + .Children()
658 + .First(x => x["rel"].ToString() == "create-checkout-capture")["href"]
659 + .ToString();
660 +
661 +// 4. Perform the capture request.
662 +var json = Newtonsoft.Json.JsonConvert.SerializeObject(new
663 +{
664 + transaction = new
665 + {
666 + description = "Captured the payment"
667 + }
668 +});
669 +var captureRequestContent = new StringContent(json, Encoding.UTF8, "application/json");
670 +var captureResponse = await httpClient.PostAsync(captureUrl, captureRequestContent);
671 +var captureResponseContent = await captureResponse.Content.ReadAsStringAsync();
672 +var capture = Newtonsoft.Json.Linq.JObject.Parse(captureResponseContent);
673 +{{/code}}
674 +
675 +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.
676 +
677 +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.>>Main.ECommerce.PayEx Checkout.Introduction.Payment.WebHome||anchor="HCapture"]]
678 +)))
679 +
680 +----
681 +
682 +~{~{/completed}}
683 +~)~)~)

Tips

You can click on the arrows next to the breadcrumb elements to quickly navigate to sibling and children pages.

Need help?

If you need help with XWiki you can contact: