{"_id":"56c31f3ec0d06a0d006680c4","project":"54c83b5aab706219009e067b","__v":0,"user":{"_id":"566be70acb3d040d00abae1d","username":"","name":"Giridaran M"},"initVersion":{"_id":"54dec8b6c2b4b70d009c3f0f","version":"1"},"hidden":false,"createdAt":"2016-02-16T13:08:14.220Z","fullscreen":false,"htmlmode":false,"html":"","body":"Orders API is the more powerful integration method available today with a bunch of extra advantages over the standard integration method.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Advantages of Orders API\"\n}\n[/block]\nOrders API brings in additional benefits to the merchants: \n\n- Single successful payment bound to an order. Prevents multiple payments\n- Capture of the payments immediately after authorization. Auto capture of payments.\n- Quick and easy query in the database. Combines multiple payment attempts for a single order.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Pre-requisite\",\n  \"body\": \"Before you go ahead with implementing Orders API in your integration, learn about the payment process flow: [Getting Started](https://docs.razorpay.com/docs/getting-started)\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Orders Workflow\"\n}\n[/block]\n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/7dd1cb8-Orders_API.png\",\n        \"Orders_API.png\",\n        1136,\n        924,\n        \"#4c7dd7\"\n      ]\n    }\n  ]\n}\n[/block]\n1. Customer places an Order on the merchant's website/app.\n2. The merchant's application server sends a create order request to Razorpay's server\n     In response, Razorpay returns an `order_id`. Store this `order_id` in your database corresponding \n      to the order on your end. \n3. Submit the `order_id` to the [Checkout Form](doc:checkout-form) on website/app.\n4. In the Checkout, the customer enters the payment details \n    After the successful payment, the following attributes are displayed in the response body: \n  *     `razorpay_payment_id`\n  *    `razorpay_order_id` \n  *    `razorpay_signature`\n5. Submit these attributes from the checkout form to the application's server.\n6. After successful authorization, the payment is captured.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Order Lifecycle\"\n}\n[/block]\n\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"`created`\",\n    \"1-0\": \"`attempted`\",\n    \"2-0\": \"`paid`\",\n    \"0-1\": \"This indicates that the order has been created.\",\n    \"1-1\": \"Payment for this order has been attempted but it hasn’t been successful.\\nThe number of attempts is indicated by the attempts field\",\n    \"2-1\": \"This is the final status of an order, when a payment has been made against it successfully.\",\n    \"h-0\": \"Status\",\n    \"h-1\": \"Description\"\n  },\n  \"cols\": 2,\n  \"rows\": 3\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Auto Capturing Payments\"\n}\n[/block]\nYou can capture the payments in either of the following ways:\n\n-  Standard Capture API, available for all integrations\n- Auto Capture, only available for integrations that have implemented Orders API.\n\nIn the standard capture, the last network request, i.e., the capture step between your server and Razorpay is required to ensure that the correct amount has been charged to the user. The capture step is required for security purposes and ensures that the `payment_id` and `amount` collected are correct. It is your responsibility to implement amount verification during capture step.\n \nIn automatic capture, the authorization is immediately followed by the capture of payments. No additional step is required to capture the payment explicitly.\nIn the  'Create Order' request, add `payment_capture = 1` to enable auto capture. An order_id thus created is passed to Checkout.  As a result, 'order_id' along with `razorpay_signature, a hexadecimal string, is returned. If the signature is valid, the payment is successful and auto captured.\n \n[block:callout]\n{\n  \"type\": \"success\",\n  \"body\": \"While `razorpay_signature` is passed and can be verified in all cases, it signifies that a payment has _also_ been captured only if you had sent `payment_capture = 1`.\",\n  \"title\": \"Note\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Verifying the Signature\"\n}\n[/block]\nThe `razorpay_signature` is returned to you by the Checkout form on successful transaction. This signature needs to be verified in your server. \n\n1. Collect the following attributes\n  *  `razorpay_payment_id` - Returned by Checkout\n  *  `razorpay_order_id`  - Returned by Checkout\n  *  `key_secret` - Available in your server\n  \n2. Generate a signature, HMAC hex digest, using SHA256 algorithm. \n    The `razorpay_payment_id` and `razorpay_order_id` fields are concatenated using the `|` (pipe) \n     symbol. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"```\\n  generated_signature = hmac_sha256(razorpay_order_id + \\\"|\\\" + razorpay_payment_id, secret);\\n \\n  if (generated_signature == razorpay_signature) {\\n    payment is successful\\n  }\\n```\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"/**\\n* This class defines common routines for generating\\n* authentication signatures for Razorpay Webhook requests.\\n*/\\npublic class Signature \\n{\\n    private static final String HMAC_SHA256_ALGORITHM = \\\"HmacSHA256\\\";\\n\\n\\n    /**\\n    * Computes RFC 2104-compliant HMAC signature.\\n    * * @param data\\n    * The data to be signed.\\n    * @param key\\n    * The signing key.\\n    * @return\\n    * The Base64-encoded RFC 2104-compliant HMAC signature.\\n    * @throws\\n    * java.security.SignatureException when signature generation fails\\n    */\\n    public static String calculateRFC2104HMAC(String data, String secret)\\n    throws java.security.SignatureException\\n    {\\n        String result;\\n        try {\\n\\n            // get an hmac_sha256 key from the raw secret bytes\\n            SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), HMAC_SHA256_ALGORITHM);\\n\\n            // get an hmac_sha256 Mac instance and initialize with the signing key\\n            Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);\\n            mac.init(signingKey);\\n\\n            // compute the hmac on input data bytes\\n            byte[] rawHmac = mac.doFinal(data.getBytes());\\n\\n            // base64-encode the hmac\\n            result = DatatypeConverter.printHexBinary(rawHmac).toLowerCase();\\n\\n        } catch (Exception e) {\\n            throw new SignatureException(\\\"Failed to generate HMAC : \\\" + e.getMessage());\\n        }\\n        return result;\\n    }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n3. The signature returned by Razorpay should be the same as that the signature you created in your server.\n\nIf you have passed `payment_capture = 1` in the initial request and validated the signature, the payment will be in `captured` state in Razorpay’s system. After verifying the signature, fetch the order in your system which has `razorpay_order_id` stored corresponding to it in your database. You can now mark this fetched order as successful and process the order.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Changes in Integration\"\n}\n[/block]\nFor implementing Orders in your integration, you must make changes in the Checkout in addition to server-side changes.\n\n**Server-side changes**\n In your system, each order from the customer, create a  `transaction_id`/`order_id`/`checkout_id` or\n  let's name this the `merchant_order_id`.This is created in your server and is NOT the order_id \n returned by Razorpay. Therefore, for every 'merchant_order_id' in your database, store the corresponding Order ID created by Razorpay, 'razorpay_order_id'.\n\n- `razorpay_order_id` (obtained after creating an order)\n- `razorpay_payment_id` (obtained after the payment was successful\n\n**Checkout Changes**\n##Sending Order ID to Checkout\nThe `razorpay_order_id` received on your server after calling the _create order_ request needs to be passed to Checkout form, on both web and mobile. This can be done by simply adding an extra key-value pair as part of the options that you are already sending:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"amount\\\": \\\"100\\\",\\n   // and other options\\n\\n\\n  \\\"order_id\\\": \\\"<razorpay_order_id>\\\"\\n}\",\n      \"language\": \"text\",\n      \"name\": \"Sample snippet\"\n    }\n  ]\n}\n[/block]\n##Getting Payment ID and Signature in Response\nThe handling of this will vary between Checkout on web and mobile app.\n\n### Checkout on Web\nIf `order_id` was passed in the options at the start of the payment, the returned `json` object is shown below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"```\\n{\\n  \\\"razorpay_payment_id\\\": \\\"pay_xxxxxxxxxxxxxx\\\",\\n  \\\"razorpay_signature\\\": \\\"<Hexadecimal String>\\\", \\n  “razorpay_order_id”: “order_xxxxxxxxxxxxxx”\\n}\\n```\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nThese two parameters need to be sent to your server for either capturing or for signature verification, if you are using auto capturing.\n\n### Checkout on Android\nYou need to be using Android SDK `v1.0.+` at least for the following to work.\n\nAndroid SDK by default only returns the `payment_id`. To get the `razorpay_signature`, your activity will need to implement the `PaymentResultWithDataListener` interface to receive the `razorpay_signature` in the `onPaymentSuccess` callback.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MerchantActivity extends Activity implements PaymentResultWithDataListener {\\n  // ...\\n\\n\\n  @Override\\n  public void onPaymentSuccess(String razorpayPaymentID, PaymentData data) {\\n       String paymentId = data.getPaymentId();\\n       String signature = data.getSignature();\\n       String orderId = data.getOrderId();\\n  }\\n\\n\\n  @Override\\n  public void onPaymentError(int code, String response, PaymentData data) {\\n \\n  }\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\n\n### Checkout on iOS\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"Implement `RazorpayPaymentCompletionProtocolWithData`:\\n\\n\\n```\\nViewController.m\\n#import <Razorpay/Razorpay.h>\\n\\n\\n@interface ViewController () <RazorpayPaymentCompletionProtocolWithData> {\\n  Razorpay *razorpay;\\n..  \\n..\\n}\\n..\\n..\\n  \\n// Any place before initiating the payment (eg. viewDidLoad)\\n- (void)viewDidLoad {\\n  [super viewDidLoad];\\n  ..\\n  ..\\n  razorpay = [Razorpay initWithKey:@\\\"rzp_test_1DP5mmOlF5G5ag\\\"\\n                       andDelegateWithData:self];\\n}\\n```\\n\\n\\nSuccess/Error handlers will receive a dictionary containing `order_id` and `signature`:\\n\\n\\n```\\n- (void)onPaymentSuccess:(nonnull NSString*)payment_id andData:(nullable NSDictionary *)response{\\n      [[[UIAlertView alloc] initWithTitle:@\\\"Payment Successful\\\" message:payment_id delegate:self cancelButtonTitle:@\\\"OK\\\" otherButtonTitles:nil] show];\\n}\\n\\n\\n- (void)onPaymentError:(int)code description:(nonnull NSString *)str andData:(nullable NSDictionary *)response {\\n      [[[UIAlertView alloc] initWithTitle:@\\\"Error\\\" message:str delegate:self cancelButtonTitle:@\\\"OK\\\" otherButtonTitles:nil] show];\\n}\",\n      \"language\": \"text\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Orders API Reference\"\n}\n[/block]\nThe order entity consists of the following fields:\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"`id`\",\n    \"0-1\": \"string\",\n    \"1-0\": \"`amount`\",\n    \"1-1\": \"integer\",\n    \"2-0\": \"`currency`\",\n    \"3-0\": \"`attempts`\",\n    \"4-0\": \"`status`\",\n    \"5-0\": \"`receipt`\",\n    \"2-1\": \"string\",\n    \"3-1\": \"integer\",\n    \"4-1\": \"string\",\n    \"5-1\": \"string\",\n    \"h-0\": \"Attribute\",\n    \"h-1\": \"Type\",\n    \"0-2\": \"Unique identifier for the order.\",\n    \"1-2\": \"The amount (in paisa) for which the order was created.\",\n    \"2-2\": \"The currency associated with this order's amount\",\n    \"3-2\": \"The number of payment attempts that have been made against this order\",\n    \"4-2\": \"This order's status in the Order lifecycle\",\n    \"5-2\": \"Your receipt id corresponding to this order. Maximum length 40 chars.\",\n    \"h-2\": \"Description\",\n    \"7-0\": \"`created_at`\",\n    \"7-1\": \"timestamp\",\n    \"7-2\": \"The timestamp corresponding to this order's creation time.\",\n    \"8-0\": \"`notes`\",\n    \"8-1\": \"object\",\n    \"8-2\": \"Object consisting of notes passed while creating an order Entity\",\n    \"6-0\": \"`payment_capture`\",\n    \"6-1\": \"boolean\",\n    \"6-2\": \"Flag for auto capturing the payment\"\n  },\n  \"cols\": 3,\n  \"rows\": 9\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"Once a successful payment is captured by you, the order status will advance to `paid`. \\n\\nThe order status will continue to remain `attempted` in the mean while. However no more payments can be made against this order.\",\n  \"title\": \"Order Status\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"post\",\n  \"title\": \"/orders\"\n}\n[/block]\nThe attributes that constitute the Order Entity are described below:\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"amount\\n_required_\",\n    \"0-1\": \"Amount for the order in paisa. Payment can only be made for this amount against the order.\",\n    \"1-0\": \"currency\\n_required_\",\n    \"1-1\": \"`INR` is the only supported currency currently.\",\n    \"2-0\": \"receipt\\n_required_\",\n    \"2-1\": \"You receipt id for this order should be passed in here. Maximum length 40 characters.\",\n    \"h-0\": \"Parameters\",\n    \"h-1\": \"Description\",\n    \"4-0\": \"notes\\n_optional_\",\n    \"4-1\": \"Object consisting of key value pairs as notes. Read more - [Notes Doc](https://docs.razorpay.com/docs/notes)\",\n    \"3-0\": \"payment_capture\\n_optional_\",\n    \"3-1\": \"Payment capture flag for auto capturing payment\"\n  },\n  \"cols\": 2,\n  \"rows\": 5\n}\n[/block]\n **Request** \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -u rzp_test_26ccbdbfe0e84b:69b2e24411e384f91213f22a \\\\\\n   -X POST \\\\\\n   --data \\\"amount=500\\\" \\\\\\n   --data \\\"currency=INR\\\" \\\\\\n   --data \\\"receipt=Receipt #20\\\" \\\\\\n   https://api.razorpay.com/v1/orders\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"Dictionary<string, object> options = new Dictionary<string, object>();\\noptions.Add(\\\"amount\\\", \\\"1000\\\");\\noptions.Add(\\\"currency\\\", \\\"INR\\\");\\noptions.Add(\\\"receipt\\\", \\\"<merchant-order-id>\\\");\\n\\nRazorpayClient client = new RazorpayClient(\\\"<key>\\\", \\\"<secret>\\\");\\nOrder order = client.Order.Create(options);\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\n**Response** \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"id\\\": \\\"order_4xbQrmEoA5WJ0G\\\",\\n  \\\"entity\\\": \\\"order\\\",\\n  \\\"amount\\\": 500,\\n  \\\"currency\\\": \\\"INR\\\",\\n  \\\"receipt\\\": \\\"Receipt #20\\\",\\n  \\\"status\\\": \\\"created\\\",\\n  \\\"attempts\\\": 0,\\n  \\\"created_at\\\": 1455696638,\\n  \\\"notes\\\": {}\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"get\",\n  \"title\": \"/orders\"\n}\n[/block]\nThis end point fetches the order details\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Params\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"from\\n_optional_\",\n    \"0-1\": \"Timestamp from when orders are to be fetched\",\n    \"2-0\": \"count\\n_optional_\",\n    \"2-1\": \"Count of orders to be fetched\\nDefault Count is 10\",\n    \"3-0\": \"skip\\n_optional_\",\n    \"3-1\": \"Numbers of orders to be skipped\\nDefault Skip is 0\",\n    \"1-0\": \"to\\n_optional_\",\n    \"1-1\": \"Timestamp up till when orders are to be fetched\",\n    \"4-0\": \"authorized\\n_optional_\",\n    \"4-1\": \"Orders for which payments are currently in authorized state\",\n    \"5-0\": \"receipt\\n_optional_\",\n    \"5-1\": \"Orders with the provided value for receipt\"\n  },\n  \"cols\": 2,\n  \"rows\": 6\n}\n[/block]\n**Response** \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"entity\\\": \\\"collection\\\",\\n  \\\"count\\\": 2,\\n  \\\"items\\\": [\\n    {\\n      \\\"id\\\": \\\"order_4xbVikJiVknbcr\\\",\\n      \\\"entity\\\": \\\"order\\\",\\n      \\\"amount\\\": 500,\\n      \\\"currency\\\": \\\"INR\\\",\\n      \\\"receipt\\\": \\\"order36\\\",\\n      \\\"status\\\": \\\"created\\\",\\n      \\\"attempts\\\": 0,\\n      \\\"created_at\\\": 1455696913,\\n      \\\"notes\\\": {}\\n    },\\n    {\\n      \\\"id\\\": \\\"order_4xbSwsPABDJ8oK\\\",\\n      \\\"entity\\\": \\\"order\\\",\\n      \\\"amount\\\": 500,\\n      \\\"currency\\\": \\\"INR\\\",\\n      \\\"receipt\\\": \\\"order33\\\",\\n      \\\"status\\\": \\\"created\\\",\\n      \\\"attempts\\\": 0,\\n      \\\"created_at\\\": 1455696756,\\n      \\\"notes\\\": {}\\n    }\\n  ]\\n}\",\n      \"language\": \"json\",\n      \"name\": null\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"get\",\n  \"title\": \"/orders/:id\"\n}\n[/block]\nThis endpoint fetches the order details of a particular order.\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Params\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"id\\n_required_\",\n    \"0-1\": \"Id of order to be fetched.\"\n  },\n  \"cols\": 2,\n  \"rows\": 1\n}\n[/block]\n**Response** \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"id\\\": \\\"order_4xbVikJiVknbcr\\\",\\n  \\\"entity\\\": \\\"order\\\",\\n  \\\"amount\\\": 600,\\n  \\\"currency\\\": \\\"INR\\\",\\n  \\\"receipt\\\": \\\"order33\\\",\\n  \\\"status\\\": \\\"created\\\",\\n  \\\"attempts\\\": 0,\\n  \\\"notes\\\": {},\\n  \\\"created_at\\\": 1455696913\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"get\",\n  \"title\": \"/orders/:id/payments\"\n}\n[/block]\nThe payments corresponding to an order can be obtained from the GET /orders/:id/payments API. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"count\\\": 1,\\n  \\\"entity\\\": \\\"collection\\\",\\n  \\\"items\\\": [\\n    {\\n      \\\"id\\\": \\\"pay_29QQoUBi66xm2f\\\",\\n      \\\"entity\\\": \\\"payment\\\",\\n      \\\"amount\\\": 600,\\n      \\\"currency\\\": \\\"INR\\\",\\n      \\\"status\\\": \\\"captured\\\",\\n      \\\"amount_refunded\\\": 0,\\n      \\\"refund_status\\\": null,\\n      \\\"email\\\": \\\"test@razorpay.com\\\",\\n      \\\"contact\\\": \\\"9364591752\\\",\\n      \\\"error_code\\\": null,\\n      \\\"error_description\\\": null,\\n      \\\"notes\\\": {},\\n      \\\"created_at\\\": 1400826750\\n    },\\n  ]\\n}\",\n      \"language\": \"json\",\n      \"name\": null\n    }\n  ]\n}\n[/block]","slug":"orders","title":"Orders"}

Orders


Orders API is the more powerful integration method available today with a bunch of extra advantages over the standard integration method. [block:api-header] { "type": "basic", "title": "Advantages of Orders API" } [/block] Orders API brings in additional benefits to the merchants: - Single successful payment bound to an order. Prevents multiple payments - Capture of the payments immediately after authorization. Auto capture of payments. - Quick and easy query in the database. Combines multiple payment attempts for a single order. [block:callout] { "type": "info", "title": "Pre-requisite", "body": "Before you go ahead with implementing Orders API in your integration, learn about the payment process flow: [Getting Started](https://docs.razorpay.com/docs/getting-started)" } [/block] [block:api-header] { "type": "basic", "title": "Orders Workflow" } [/block] [block:image] { "images": [ { "image": [ "https://files.readme.io/7dd1cb8-Orders_API.png", "Orders_API.png", 1136, 924, "#4c7dd7" ] } ] } [/block] 1. Customer places an Order on the merchant's website/app. 2. The merchant's application server sends a create order request to Razorpay's server In response, Razorpay returns an `order_id`. Store this `order_id` in your database corresponding to the order on your end. 3. Submit the `order_id` to the [Checkout Form](doc:checkout-form) on website/app. 4. In the Checkout, the customer enters the payment details After the successful payment, the following attributes are displayed in the response body: * `razorpay_payment_id` * `razorpay_order_id` * `razorpay_signature` 5. Submit these attributes from the checkout form to the application's server. 6. After successful authorization, the payment is captured. [block:api-header] { "type": "basic", "title": "Order Lifecycle" } [/block] [block:parameters] { "data": { "0-0": "`created`", "1-0": "`attempted`", "2-0": "`paid`", "0-1": "This indicates that the order has been created.", "1-1": "Payment for this order has been attempted but it hasn’t been successful.\nThe number of attempts is indicated by the attempts field", "2-1": "This is the final status of an order, when a payment has been made against it successfully.", "h-0": "Status", "h-1": "Description" }, "cols": 2, "rows": 3 } [/block] [block:api-header] { "type": "basic", "title": "Auto Capturing Payments" } [/block] You can capture the payments in either of the following ways: - Standard Capture API, available for all integrations - Auto Capture, only available for integrations that have implemented Orders API. In the standard capture, the last network request, i.e., the capture step between your server and Razorpay is required to ensure that the correct amount has been charged to the user. The capture step is required for security purposes and ensures that the `payment_id` and `amount` collected are correct. It is your responsibility to implement amount verification during capture step. In automatic capture, the authorization is immediately followed by the capture of payments. No additional step is required to capture the payment explicitly. In the 'Create Order' request, add `payment_capture = 1` to enable auto capture. An order_id thus created is passed to Checkout. As a result, 'order_id' along with `razorpay_signature, a hexadecimal string, is returned. If the signature is valid, the payment is successful and auto captured. [block:callout] { "type": "success", "body": "While `razorpay_signature` is passed and can be verified in all cases, it signifies that a payment has _also_ been captured only if you had sent `payment_capture = 1`.", "title": "Note" } [/block] [block:api-header] { "type": "basic", "title": "Verifying the Signature" } [/block] The `razorpay_signature` is returned to you by the Checkout form on successful transaction. This signature needs to be verified in your server. 1. Collect the following attributes * `razorpay_payment_id` - Returned by Checkout * `razorpay_order_id` - Returned by Checkout * `key_secret` - Available in your server 2. Generate a signature, HMAC hex digest, using SHA256 algorithm. The `razorpay_payment_id` and `razorpay_order_id` fields are concatenated using the `|` (pipe) symbol. [block:code] { "codes": [ { "code": "```\n generated_signature = hmac_sha256(razorpay_order_id + \"|\" + razorpay_payment_id, secret);\n \n if (generated_signature == razorpay_signature) {\n payment is successful\n }\n```", "language": "text" } ] } [/block] [block:code] { "codes": [ { "code": "/**\n* This class defines common routines for generating\n* authentication signatures for Razorpay Webhook requests.\n*/\npublic class Signature \n{\n private static final String HMAC_SHA256_ALGORITHM = \"HmacSHA256\";\n\n\n /**\n * Computes RFC 2104-compliant HMAC signature.\n * * @param data\n * The data to be signed.\n * @param key\n * The signing key.\n * @return\n * The Base64-encoded RFC 2104-compliant HMAC signature.\n * @throws\n * java.security.SignatureException when signature generation fails\n */\n public static String calculateRFC2104HMAC(String data, String secret)\n throws java.security.SignatureException\n {\n String result;\n try {\n\n // get an hmac_sha256 key from the raw secret bytes\n SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), HMAC_SHA256_ALGORITHM);\n\n // get an hmac_sha256 Mac instance and initialize with the signing key\n Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);\n mac.init(signingKey);\n\n // compute the hmac on input data bytes\n byte[] rawHmac = mac.doFinal(data.getBytes());\n\n // base64-encode the hmac\n result = DatatypeConverter.printHexBinary(rawHmac).toLowerCase();\n\n } catch (Exception e) {\n throw new SignatureException(\"Failed to generate HMAC : \" + e.getMessage());\n }\n return result;\n }\n}", "language": "java" } ] } [/block] 3. The signature returned by Razorpay should be the same as that the signature you created in your server. If you have passed `payment_capture = 1` in the initial request and validated the signature, the payment will be in `captured` state in Razorpay’s system. After verifying the signature, fetch the order in your system which has `razorpay_order_id` stored corresponding to it in your database. You can now mark this fetched order as successful and process the order. [block:api-header] { "type": "basic", "title": "Changes in Integration" } [/block] For implementing Orders in your integration, you must make changes in the Checkout in addition to server-side changes. **Server-side changes** In your system, each order from the customer, create a `transaction_id`/`order_id`/`checkout_id` or let's name this the `merchant_order_id`.This is created in your server and is NOT the order_id returned by Razorpay. Therefore, for every 'merchant_order_id' in your database, store the corresponding Order ID created by Razorpay, 'razorpay_order_id'. - `razorpay_order_id` (obtained after creating an order) - `razorpay_payment_id` (obtained after the payment was successful **Checkout Changes** ##Sending Order ID to Checkout The `razorpay_order_id` received on your server after calling the _create order_ request needs to be passed to Checkout form, on both web and mobile. This can be done by simply adding an extra key-value pair as part of the options that you are already sending: [block:code] { "codes": [ { "code": "{\n \"amount\": \"100\",\n // and other options\n\n\n \"order_id\": \"<razorpay_order_id>\"\n}", "language": "text", "name": "Sample snippet" } ] } [/block] ##Getting Payment ID and Signature in Response The handling of this will vary between Checkout on web and mobile app. ### Checkout on Web If `order_id` was passed in the options at the start of the payment, the returned `json` object is shown below: [block:code] { "codes": [ { "code": "```\n{\n \"razorpay_payment_id\": \"pay_xxxxxxxxxxxxxx\",\n \"razorpay_signature\": \"<Hexadecimal String>\", \n “razorpay_order_id”: “order_xxxxxxxxxxxxxx”\n}\n```", "language": "javascript" } ] } [/block] These two parameters need to be sent to your server for either capturing or for signature verification, if you are using auto capturing. ### Checkout on Android You need to be using Android SDK `v1.0.+` at least for the following to work. Android SDK by default only returns the `payment_id`. To get the `razorpay_signature`, your activity will need to implement the `PaymentResultWithDataListener` interface to receive the `razorpay_signature` in the `onPaymentSuccess` callback. [block:code] { "codes": [ { "code": "public class MerchantActivity extends Activity implements PaymentResultWithDataListener {\n // ...\n\n\n @Override\n public void onPaymentSuccess(String razorpayPaymentID, PaymentData data) {\n String paymentId = data.getPaymentId();\n String signature = data.getSignature();\n String orderId = data.getOrderId();\n }\n\n\n @Override\n public void onPaymentError(int code, String response, PaymentData data) {\n \n }", "language": "text" } ] } [/block] ### Checkout on iOS [block:code] { "codes": [ { "code": "Implement `RazorpayPaymentCompletionProtocolWithData`:\n\n\n```\nViewController.m\n#import <Razorpay/Razorpay.h>\n\n\n@interface ViewController () <RazorpayPaymentCompletionProtocolWithData> {\n Razorpay *razorpay;\n.. \n..\n}\n..\n..\n \n// Any place before initiating the payment (eg. viewDidLoad)\n- (void)viewDidLoad {\n [super viewDidLoad];\n ..\n ..\n razorpay = [Razorpay initWithKey:@\"rzp_test_1DP5mmOlF5G5ag\"\n andDelegateWithData:self];\n}\n```\n\n\nSuccess/Error handlers will receive a dictionary containing `order_id` and `signature`:\n\n\n```\n- (void)onPaymentSuccess:(nonnull NSString*)payment_id andData:(nullable NSDictionary *)response{\n [[[UIAlertView alloc] initWithTitle:@\"Payment Successful\" message:payment_id delegate:self cancelButtonTitle:@\"OK\" otherButtonTitles:nil] show];\n}\n\n\n- (void)onPaymentError:(int)code description:(nonnull NSString *)str andData:(nullable NSDictionary *)response {\n [[[UIAlertView alloc] initWithTitle:@\"Error\" message:str delegate:self cancelButtonTitle:@\"OK\" otherButtonTitles:nil] show];\n}", "language": "text" } ] } [/block] [block:api-header] { "type": "basic", "title": "Orders API Reference" } [/block] The order entity consists of the following fields: [block:parameters] { "data": { "0-0": "`id`", "0-1": "string", "1-0": "`amount`", "1-1": "integer", "2-0": "`currency`", "3-0": "`attempts`", "4-0": "`status`", "5-0": "`receipt`", "2-1": "string", "3-1": "integer", "4-1": "string", "5-1": "string", "h-0": "Attribute", "h-1": "Type", "0-2": "Unique identifier for the order.", "1-2": "The amount (in paisa) for which the order was created.", "2-2": "The currency associated with this order's amount", "3-2": "The number of payment attempts that have been made against this order", "4-2": "This order's status in the Order lifecycle", "5-2": "Your receipt id corresponding to this order. Maximum length 40 chars.", "h-2": "Description", "7-0": "`created_at`", "7-1": "timestamp", "7-2": "The timestamp corresponding to this order's creation time.", "8-0": "`notes`", "8-1": "object", "8-2": "Object consisting of notes passed while creating an order Entity", "6-0": "`payment_capture`", "6-1": "boolean", "6-2": "Flag for auto capturing the payment" }, "cols": 3, "rows": 9 } [/block] [block:callout] { "type": "warning", "body": "Once a successful payment is captured by you, the order status will advance to `paid`. \n\nThe order status will continue to remain `attempted` in the mean while. However no more payments can be made against this order.", "title": "Order Status" } [/block] [block:api-header] { "type": "post", "title": "/orders" } [/block] The attributes that constitute the Order Entity are described below: [block:parameters] { "data": { "0-0": "amount\n_required_", "0-1": "Amount for the order in paisa. Payment can only be made for this amount against the order.", "1-0": "currency\n_required_", "1-1": "`INR` is the only supported currency currently.", "2-0": "receipt\n_required_", "2-1": "You receipt id for this order should be passed in here. Maximum length 40 characters.", "h-0": "Parameters", "h-1": "Description", "4-0": "notes\n_optional_", "4-1": "Object consisting of key value pairs as notes. Read more - [Notes Doc](https://docs.razorpay.com/docs/notes)", "3-0": "payment_capture\n_optional_", "3-1": "Payment capture flag for auto capturing payment" }, "cols": 2, "rows": 5 } [/block] **Request** [block:code] { "codes": [ { "code": "curl -u rzp_test_26ccbdbfe0e84b:69b2e24411e384f91213f22a \\\n -X POST \\\n --data \"amount=500\" \\\n --data \"currency=INR\" \\\n --data \"receipt=Receipt #20\" \\\n https://api.razorpay.com/v1/orders", "language": "curl" }, { "code": "Dictionary<string, object> options = new Dictionary<string, object>();\noptions.Add(\"amount\", \"1000\");\noptions.Add(\"currency\", \"INR\");\noptions.Add(\"receipt\", \"<merchant-order-id>\");\n\nRazorpayClient client = new RazorpayClient(\"<key>\", \"<secret>\");\nOrder order = client.Order.Create(options);", "language": "csharp" } ] } [/block] **Response** [block:code] { "codes": [ { "code": "{\n \"id\": \"order_4xbQrmEoA5WJ0G\",\n \"entity\": \"order\",\n \"amount\": 500,\n \"currency\": \"INR\",\n \"receipt\": \"Receipt #20\",\n \"status\": \"created\",\n \"attempts\": 0,\n \"created_at\": 1455696638,\n \"notes\": {}\n}", "language": "json" } ] } [/block] [block:api-header] { "type": "get", "title": "/orders" } [/block] This end point fetches the order details [block:parameters] { "data": { "h-0": "Params", "h-1": "Description", "0-0": "from\n_optional_", "0-1": "Timestamp from when orders are to be fetched", "2-0": "count\n_optional_", "2-1": "Count of orders to be fetched\nDefault Count is 10", "3-0": "skip\n_optional_", "3-1": "Numbers of orders to be skipped\nDefault Skip is 0", "1-0": "to\n_optional_", "1-1": "Timestamp up till when orders are to be fetched", "4-0": "authorized\n_optional_", "4-1": "Orders for which payments are currently in authorized state", "5-0": "receipt\n_optional_", "5-1": "Orders with the provided value for receipt" }, "cols": 2, "rows": 6 } [/block] **Response** [block:code] { "codes": [ { "code": "{\n \"entity\": \"collection\",\n \"count\": 2,\n \"items\": [\n {\n \"id\": \"order_4xbVikJiVknbcr\",\n \"entity\": \"order\",\n \"amount\": 500,\n \"currency\": \"INR\",\n \"receipt\": \"order36\",\n \"status\": \"created\",\n \"attempts\": 0,\n \"created_at\": 1455696913,\n \"notes\": {}\n },\n {\n \"id\": \"order_4xbSwsPABDJ8oK\",\n \"entity\": \"order\",\n \"amount\": 500,\n \"currency\": \"INR\",\n \"receipt\": \"order33\",\n \"status\": \"created\",\n \"attempts\": 0,\n \"created_at\": 1455696756,\n \"notes\": {}\n }\n ]\n}", "language": "json", "name": null } ] } [/block] [block:api-header] { "type": "get", "title": "/orders/:id" } [/block] This endpoint fetches the order details of a particular order. [block:parameters] { "data": { "h-0": "Params", "h-1": "Description", "0-0": "id\n_required_", "0-1": "Id of order to be fetched." }, "cols": 2, "rows": 1 } [/block] **Response** [block:code] { "codes": [ { "code": "{\n \"id\": \"order_4xbVikJiVknbcr\",\n \"entity\": \"order\",\n \"amount\": 600,\n \"currency\": \"INR\",\n \"receipt\": \"order33\",\n \"status\": \"created\",\n \"attempts\": 0,\n \"notes\": {},\n \"created_at\": 1455696913\n}", "language": "json" } ] } [/block] [block:api-header] { "type": "get", "title": "/orders/:id/payments" } [/block] The payments corresponding to an order can be obtained from the GET /orders/:id/payments API. [block:code] { "codes": [ { "code": "{\n \"count\": 1,\n \"entity\": \"collection\",\n \"items\": [\n {\n \"id\": \"pay_29QQoUBi66xm2f\",\n \"entity\": \"payment\",\n \"amount\": 600,\n \"currency\": \"INR\",\n \"status\": \"captured\",\n \"amount_refunded\": 0,\n \"refund_status\": null,\n \"email\": \"test@razorpay.com\",\n \"contact\": \"9364591752\",\n \"error_code\": null,\n \"error_description\": null,\n \"notes\": {},\n \"created_at\": 1400826750\n },\n ]\n}", "language": "json", "name": null } ] } [/block]