docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Server-side implementation of UDP

    The server-side integration consists of the following steps:

    • Query orders
    • Receive callback notifications

    Querying Orders

    Your game can query UDP about orders by calling an HTTP GET request.

    img

    Querying UDP about orders:

    https://distribute.dashboard.unity.com/udp/developer/api/order?orderQueryToken=<orderQueryToken>&orderId=<orderId>&clientId=<clientId>&sign=<sign>
    

    Parameters in the request:

    Attribute name Format Required/Optional Description Example
    orderQueryToken String Required The order query token returned by the client SDK when finishing a purchase. The token needs to be encoded Base64 before being used in the query.(UDP SDK will return PurchaseInfo.OrderQueryToken) eyJjaGFubmVsUHJvZHVjdElkIjoiaWFwLl9mM2YzZiIsImNoYW5uZWxUeXBlIjoiQVBUT0lERSIsImNsaWVudElkIjoiQUFJZ3g5VmNGaDJZQ1ZxbUs2VWNDUSIsImNwT3JkZXJJZCI6IjJhNGQ5MWY4NDgzZjQ3YjlhYzFhNGY5MDAwZDVhNTRhIiwicGFja2FnZU5hbWUiOiJjb20udW5pdHkudW5pdHl0ZXN0Z2FtZV9mZWZ3In0=
    orderId String Required The orderId returned by the client SDK when finishing a purchase.(UDP SDK will return PurchaseInfo.GameOrderId) 2a4d91f8483f47b9ac1a4f9000d5a54a
    clientId String Required The clientId can be found in the Game info - integration information of UDP console AAIgx9VcFh2YCVqmK6UcCQ
    sign String Required Generate signature with orderQueryToken and client secret, MD5.hash(orderQueryToken + clientSecret).
    Client Secret can also been found in the Game info - integration information of UDP console.
    Client Secret: KKcCyAgej06MxjKX31WuFNeHSaTJAjLDlgoDWsPJDAM

    Sign: 90a4e440897623c7cd0b2b80a97c267e

    Parameters in the response:

    Attribute name Format Required /optional Description Example
    clientId String Required The clientId that is returned by Unity after the game has created a client in the Unity IAP. Q4AnJDW2-rxLAPujqrk1zQ
    cpOrderId String Required The order ID assigned by your game, or Unity if the game does not generate it. 66mea52wne
    channelType String Required Channel type APTOIDE,CLOUDMOOLAH
    status String Required Indicates the status of the order. SUCCESS, FAILED, UNCONFIRMED
    productId String Required The product ID associated with the order product_1
    amount String Required The payment amount of the order 1
    quantity Integer Required Indicates the quantity of the product. 1
    currency ISO 4217 Required The currency used to purchase the product CNY
    country ISO 3166-2 Required The country or geographic region in which the user is located CN
    paidTime ISO8601 yyyy-MM-ddThh:mm:ssXXX, UTC timezone Required Specifies the time when the order is paid. 2017-03-08T06:43:20Z
    rev String Required The revision of the order (only for update) 0
    extension Json String Optional The developer payload used to add reference information {"abc" : "123"}

    img

    Here is an example request from your game server to the UDP server and response from the UDP server back to your game server:

    The content of the orderQueryToken:

    {“channelProductId”:“iap._f3f3f”,“channelType”:“APTOIDE”,“clientId”:“AAIgx9VcFh2YCVqmK6UcCQ”,“cpOrderId”:“2a4d91f8483f47b9ac1a4f9000d5a54a”,“packageName”:“com.unity.unitytestgame_fefw”}
    

    Being encoded using Base64, the orderQueryToken:

    eyJjaGFubmVsUHJvZHVjdElkIjoiaWFwLl9mM2YzZiIsImNoYW5uZWxUeXBlIjoiQVBUT0lERSIsImNsaWVudElkIjoiQUFJZ3g5VmNGaDJZQ1ZxbUs2VWNDUSIsImNwT3JkZXJJZCI6IjJhNGQ5MWY4NDgzZjQ3YjlhYzFhNGY5MDAwZDVhNTRhIiwicGFja2FnZU5hbWUiOiJjb20udW5pdHkudW5pdHl0ZXN0Z2FtZV9mZWZ3In0=
    

    orderId:

    2a4d91f8483f47b9ac1a4f9000d5a54a
    

    clientId:

    AAIgx9VcFh2YCVqmK6UcCQ
    

    clientSecret:

    KKcCyAgej06MxjKX31WuFNeHSaTJAjLDlgoDWsPJDAM
    

    Sign:

    90a4e440897623c7cd0b2b80a97c267e
    

    Request:

    Get 
    https://distribute.dashboard.unity.com/udp/developer/api/order?orderQueryToken=eyJjaGFubmVsUHJvZHVjdElkIjoiaWFwLl9mM2YzZiIsImNoYW5uZWxUeXBlIjoiQVBUT0lERSIsImNsaWVudElkIjoiQUFJZ3g5VmNGaDJZQ1ZxbUs2VWNDUSIsImNwT3JkZXJJZCI6IjJhNGQ5MWY4NDgzZjQ3YjlhYzFhNGY5MDAwZDVhNTRhIiwicGFja2FnZU5hbWUiOiJjb20udW5pdHkudW5pdHl0ZXN0Z2FtZV9mZWZ3In0%3D&orderId=2a4d91f8483f47b9ac1a4f9000d5a54a&clientId=AAIgx9VcFh2YCVqmK6UcCQ&sign=90a4e440897623c7cd0b2b80a97c267e
    

    Response:

    {
    "ClientId":"AAIgx9VcFh2YCVqmK6UcCQ",
    "CpOrderId":"2a4d91f8483f47b9ac1a4f9000d5a54a",
    "ProductId":"iap._f3f3f",
    "ChannelType":"APTOIDE",
    "Currency":"APPC",
    "Amount":"0.1",
    "Country":"HK",
    "Quantity":1,
    "Rev":"0",
    "Status":"SUCCESS",
    "PaidTime":"2019-06-12T03:59:42Z",
    "Extension":"unity://unity3d.com?cpOrderId=2a4d91f8483f47b9ac1a4f9000d5a54a\u0026payload=payload2"
    }
    

    Receiving callback notifications

    After a purchase succeeds, if you have specified a callback URL, the UDP server notifies the game server with the payment result. Implement an HTTP GET request and accept the following query parameters:

    Attribute Name Format Required/Optional Description
    payload Json String Required The contents of the purchase order. See more in Json payload.
    signature String Required The PKCS1 v1.5 signature of the payload

    Using the certificate

    You can verify the certificate using the Unity Client RSA Public Key. If the certificate passes verification, extract the RSA public key from the certificate and use this key to verify the signature. The signature is generated by encrypting the payload with the by RSA-SHA1 algorithm.

    Here is an example:

    Public key:

    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4qxbtUqsrvwk2FZ+F2J0EkUDKLdZSVE3qPgxzKxOrgScGrCZULLav9CPzRP91HN9GccvmShH2bsegP3RVtMdwU1eV7C2JdOW1sylCyKIgylCT8tLdQeUMRaIlt7fOfl+k3bkUouWJx8WnrQYM6a7oDeCGklIlekvpQ2NcS1eg7Jp646vBzyu8FMBiuj5LZOhCJg/XXs0kRpvSOBAPndUu/HgqD9aFaXNZBxMN++efxq6PnAVRzRdTtRur+OZSBGjXxgaBKrdbXCkEM3fkMgXP9egq6vnzCiQhZ7UDFXtXQ3DPqviqrTY5WsR9t4X6JxCXo6yGlQAEK/ft9MWN13nrQIDAQAB
    

    Request body:

    {
        "signature": "swWWZpg0/Y26XBohvqqC/for4nyhS5zwzru5s8AJI7YYC+ECHOk7KQjOyFw7cWxM3QNpd7N7E7Umy3vYwDXjV2Y4BLnuJy5gGIpO5jKU4xBNQf793FmI0Fk93YrU31QyiIjXymg1O/H1nKSJXqMz6bycBugiStqsuGp1/CctTHE0Dpv4hC6fZoNWIHYpPJQuKh4DyP1lgE32omcuKUh7IAQduRPDa+qiYJRCA8bV17xK6T8ajS3RlhKue9hjE2a21t8p017ViaOS5OWdzptUwgnWaFi6gs1k0cjdn7o/0QJEgk5j6a8WYE/S8F7YfsYcAwUQV4KY3ex0ULsH3GQEGA==",
    
        "payload": "{\"ClientId\":\"Q_sX9CXfn-rTcWmpP9VEfw\",\"CpOrderId\":\"0bckmoqhel5yd13f\",\"ProductId\":\"com.mystudio.mygame.productid1\",\"ChannelType\":\"APTOIDE\",\"Currency\":\"APPC\",\"Amount\":\"1.01\",\"Country\":\"CHINA\",\"Quantity\":1,\"Rev\":\"0\",\"Status\":\"SUCCESS\",\"PaidTime\":\"2018-09-28T06:43:20Z\",\"Extension\":\"{\\\"key\\\":\\\"value\\\"}\"}"
    
    }
    

    A code sample showing how to verify the certificate in Go:

    func verify(data []byte, publicKey string, sign string) bool {
    
       decodePublic, err := base64.StdEncoding.DecodeString(publicKey)
    
       if err != nil {
    
           panic(err)
    
       }
    
       pubInterface, err := x509.ParsePKIXPublicKey(decodePublic)
    
       if err != nil {
    
           panic(err)
    
       }
    
       pub := pubInterface.(*rsa.PublicKey)
    
       decodeSign, err := base64.StdEncoding.DecodeString(sign)
    
       if err != nil {
    
           return false
    
       }
    
       sh1 := sha1.New()
    
       sh1.Write(data)
    
       hashData := sh1.Sum(nil)
    
       err = rsa.VerifyPKCS1v15(pub, crypto.SHA1, hashData, decodeSign)
    
       if err != nil {
    
           return false
    
       }
    
       return true
    
    }
    

    Here is the content of a JSON payload:

    Attribute Name Format Required/Optional Description Example
    cpOrderId String Required The unique order identifier assigned by your game. 0bckmoqhel5yd13f
    status String Required Indicates the status of the order. SUCCESS
    amount String Required Specifies the amount of money that the order cost. 1.01
    productId String Required Specifies the unique identifiers of the products that belong to the order. com.mystudio.mygame.productid1
    payTime ISO8601 yyyy-MM-ddThh:mm:ssZ, UTC timezone Required The time when the order was paid. 2018-09-28T06:43:20Z
    country ISO 3166-2 Required The country where the order was paid. CHINA
    currency ISO 4217 or cryptocurrency type Required The currency of the country where the order was placed. APPC
    quantity Integer Required The number of products in the order. 1
    clientId String Required The unique client identifier that is returned after your game generates a client in Unity IAP. Q_sX9CXfn-rTcWmpP9VEfw
    extension String Optional The developer payload which is used to contain reference information for developers. "{"key":"value"}"
    In This Article
    Back to top
    Copyright © 2025 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)