---
description: Guide to migrate your existing subscriptions to Purchasely.
---

# Migrate to Purchasely

## Quick overview of the migration process

A quick overview of the migration process to help you understand why we are doing things when we'll go deeper in the explanations:

1. **Configure your app/products/plans in the Purchasely console**: without this data, we won't be able to do anything
2. **Send us every new subscription created on you side with a call on our API**: this step ensure we'll know everything about the subscriptions created from this point in time (needed for the users still using old versions of your app)
3. **Extract your existing subscriptions into a CSV**: this step ensure we'll known everything about the subscriptions created in the past
4. **Release your new app**: at this point, our backend will know every past/present/future subscriptions and you'll be able to release your app, everything will work smoothly.

## Migration process in details

### 1. Configure your app/products/plans in the Purchasely console

Everything is explained here: [https://docs.purchasely.com/quick-start/console-configuration](https://docs.purchasely.com/quick-start/console-configuration)

### 2. Send us every new subscription created on you side with a call on our API

## Post receipt

<mark style="color:green;">`POST`</mark> `https://s2s.purchasely.io/receipts`

This endpoint allows you to update Purchasely with new purchases made by a previous version of your app.

#### Headers

| Name            | Type   | Description                                                              |
| --------------- | ------ | ------------------------------------------------------------------------ |
| X-PLATFORM-TYPE | string | The subscription platform (`APP_STORE`, `PLAY_STORE`, `APPGALLERY`)      |
| X-API-KEY       | string | API Key associated to your application (available in Purchasely console) |

#### Request Body

| Name                 | Type    | Description                                                                                                                                   |
| -------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| intro\_cycles        | integer | number of periods the intro price is available: for a double 4-weeks intro pricing, the intro\_cycles would be `2`                            |
| intro\_duration      | integer | number of periods the intro price is available: for a double 4-weeks intro pricing, the intro\_duration would be `4`                          |
| intro\_period        | string  | unit of a subscription's intro period (`day`, `week`, `month`, `year`): for a double 4-weeks intro pricing, the intro\_period would be `week` |
| duration             | integer | number of periods before renewing: for a subscription renewing every 3 months, the duration would be `3`                                      |
| period               | string  | unit of a subscription's duration (`day`, `week`, `month`, `year`): for a subscription renewing every 3 months, the period would be `month`   |
| intro\_amount\_cents | integer | subscriptions's intro price in cents ($12.35 => 1235, $12.3 => 1230, $12 => 1200)                                                             |
| quantity             | integer | number of products purchased (always 1 for subscriptions)                                                                                     |
| currency             | string  | ISO 4217 format (`USD`, `EUR`, ...)                                                                                                           |
| amount\_cents        | integer | subscription's price in cents ($12.35 => 1235, $12.3 => 1230, $12 => 1200)                                                                    |
| store\_product\_id   | string  | product id as defined in your store console                                                                                                   |
| user\_id             | string  | id of your user as defined in your backend                                                                                                    |
| purchase\_token      | string  | **\[GOOGLE PLAY ONLY]** purchase token given by the SDK during the purchase, used to request Play Store servers                               |
| receipt\_data        | string  | **\[APP STORE ONLY]** Base64 encoded receipt data given by the SDK during the purchase, used to request App Store servers                     |

{% tabs %}
{% tab title="200 Cake successfully retrieved." %}
```
{ "id": "transaction-id" }
```
{% endtab %}

{% tab title="403 (X-API-KEY, X-PLATFORM-TYPE) doesn't match any platform" %}
```
{ "errors": ["unknown api_key"] }
```
{% endtab %}

{% tab title="422 Returned when a parameter is invalid" %}
```
{ "errors": ["missing mandatory property \"purchase_token\""] }
```
{% endtab %}
{% endtabs %}

{% hint style="info" %}
&#x20; The not-mandatory-fields are highly recommended: we use them to calculate the LTV (life-time value) of your users and track your revenues.
{% endhint %}

#### 2.1. Body parameters exemple

{% tabs %}
{% tab title="Apple App Store" %}
```javascript
{
  // App Store specific
  "receipt_data": "abcdFEbsbs",
  
  // Common
  "user_id": "1234",
  "store_product_id": "com.foo.bar",
  "amount_cents": 1235,
  "currency": "EUR",
  "quantity": 1,
  "intro_amount_cents": 0,
  "intro_cycles": 2,
  "intro_duration": 4,
  "intro_period": "week",
  "duration": 3,
  "period": "month"
}
```
{% endtab %}

{% tab title="Google Play Store" %}
```javascript
{
  // Play Store specific
  "purchase_token": "abcdFEbsbs",
  
  // Common
  "user_id": "1234",
  "store_product_id": "com.foo.bar",
  "amount_cents": 1235,
  "currency": "EUR",
  "quantity": 1,
  "intro_amount_cents": 0,
  "intro_cycles": 2,
  "intro_duration": 4,
  "intro_period": "week",
  "duration": 3,
  "period": "month"
}
```
{% endtab %}
{% endtabs %}

#### 2.2. Requests example

{% tabs %}
{% tab title="cURL" %}
```bash
curl \
  --request POST \
  -i \
  -H "Content-Type: application/json" \
  -H "X-API-KEY:00000000-1111-2222-3333-444444444444" \
  -H "X-PLATFORM-TYPE:PLAY_STORE" \
  --data '{"purchase_token":"aaaNNNcccDDDeeeFFF","user_id":"1234567890","store_product_id":"com.my.product","amount_cents":199,"currency":"EUR","quantity":1,"intro_amount_cents":0,"intro_cycles":0, "intro_duration":0,"intro_period":null,"duration":3,"period":"month"}' \
  https://s2s.purchasely.io/receipts
```
{% endtab %}

{% tab title="ruby" %}
```ruby
require 'net/http'
require 'json'

# Url
url = URI('https://s2s.purchasely.io/receipts')
request = Net::HTTP::Post.new(url)

# Headers
request['Content-Type'] = 'application/json'
request['X-API-KEY'] = '00000000-1111-2222-3333-444444444444'
request['X-PLATFORM-TYPE'] = 'PLAY_STORE'

# Payload
payload = {
  purchase_token: "abcdeFGHIJklmnoPQRSTuvwxyZ",
  user_id: "1234567890",
  store_product_id: "product.monthly",
  amount_cents: 119,
  currency: "EUR",
  quantity: 1,
  intro_amount_cents: 0,
  intro_cycles: 0,
  intro_duration: 0,
  intro_period: nil,
  duration: 3,
  intro_period: "month"
}
request.body = payload.to_json

# Send request
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request(request)

# Response
case response.code
when '200'
  transaction_id = JSON.parse(response.body)['id']
when '403', '422'
  errors = JSON.parse(response.body)['errors']
end
```
{% endtab %}
{% endtabs %}

### 3. Extract your existing subscriptions into a CSV

It's time to extract all you existing subscriptions (active and expired)!

As before, we'll need different fields, depending of the platform (same rules apply for mandatory/recommended fields).

When extracted, send us these files and we'll take care of importing them.

#### 3.1. App Store

{% code title="example.csv" %}
```
user_id;receipt_data;store_product_id;amount_cents;currency;quantity;intro_amount_cents;intro_cycles;intro_duration;intro_period;duration;period
1234;abcdFEbsbs;com.foo.bar;1235;EUR;1;0;2;4;week;3;month
```
{% endcode %}

{% file src="https://3348776246-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHAzdlUVqKyZvwTnNIE%2F-MUs_DpotamjfNajlJFx%2F-MUsaBLOU-BAhfuO-8j4%2Fpurchasely-appstore-migration.csv?alt=media&token=95cc6b1f-6bdd-4797-a32a-34ee9ea3240d" %}

#### 3.2. Play Store

{% code title="example.csv" %}
```
user_id;purchase_token;store_product_id;amount_cents;currency;quantity;intro_amount_cents;intro_cycles;intro_duration;intro_period;duration;period
1234;abcdFEbsbs;com.foo.bar;1500;EUR;1;0;1;5;day;3;month
```
{% endcode %}

{% file src="https://3348776246-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MHAzdlUVqKyZvwTnNIE%2F-MUs_DpotamjfNajlJFx%2F-MUsaLIiLrBOPymxibJh%2Fpurchasely-playstore-migration.csv?alt=media&token=59408606-11e6-417f-b697-648dc73cd791" %}

### 4. Release your new app

When everything is ok on our side, we'll send you a confirmation that you can release your apps.
