General Information
Propose corrections on GitHub
QIWI Wallet API makes it easy to automate getting info on your account's state in QIWI Wallet service and making financial operations.
API uses HTTPS requests and JSON-formatted responses.
API methods are accessible after the user is registered in QIWI Wallet service.
Service data
Token issue to authorize API requests has been stopped. Sorry for the inconvenience.
Authorization
Parameter | Description | Type |
---|---|---|
token | Token to authorize API requests. Token is valid within one month after its issuing. | String |
API Access
OAuth token issue has been stopped. Sorry for the inconvenience.
Main URL address to call API methods (unless explicitly stated):
https://edge.qiwi.com
To make a successful request of API methods, you need:
- Correct HTTP headers:
Accept
andContent-Type
, as designated in a method description. - URL composed according to the method reference
- OAuth token issued for your QIWI Wallet. Some requests do not require it though.
Authorization
OAuth token issue for authorization has been stopped. Sorry for the inconvenience.
Authorization data
QIWI Wallet API implements OAuth 2.0 open authorization protocol specification. A user registers or authenticates on https://qiwi.com QIWI Wallet site and requests a token with a certain scopes. Token issue is confirmed by SMS code.
Authorization example
curl "server address" \
--header "Authorization: Bearer jMyN22DQxMjM6NDUzRmRnZDQ0Mw11212e"
- As a result of authentication in QIWI Wallet site, you got the token:
U1QtOTkwMTAyLWNud3FpdWhmbzg3M
-
Add the token to
Authorization: Bearer
HTTP header. -
The header has to be added to each API request:
Authorization: Bearer U1QtOTkwMTAyLWNud3FpdWhmbzg3M
User's Profile API
Edit on GitHub
The API returns information about your profile - a set of user data and settings of your QIWI Wallet.
Request → GET
curl "https://edge.qiwi.com/person-profile/v1/profile/current?authInfoEnabled=false" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /person-profile/v1/profile/current HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
# User profile
def get_profile(api_access_token):
s7 = requests.Session()
s7.headers['Accept']= 'application/json'
s7.headers['authorization'] = 'Bearer ' + api_access_token
p = s7.get('https://edge.qiwi.com/person-profile/v1/profile/current?authInfoEnabled=true&contractInfoEnabled=true&userInfoEnabled=true')
return p.json()
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# Full info
profile = get_profile(api_access_token)
# Blocking status
profile['contractInfo']['blocked']
# Identification level
profile['contractInfo']['identificationInfo'][0]['identificationLevel']
# Linked email
profile['authInfo']['boundEmail']
URL /person-profile/v1/profile/current?parameter=value
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
These options are transmitted in the URL query:
Name | Type | Description |
---|---|---|
authInfoEnabled | Boolean | Flag to get authorization settings. By default, true |
contractInfoEnabled | Boolean | Flag to get your QIWI wallet data. By default, true |
userInfoEnabled | Boolean | Flag to get other user data. By default, true |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"authInfo": {
"boundEmail": "m@ya.ru",
"ip": "81.210.201.22",
"lastLoginDate": "2017-07-27T06:51:06.099Z",
"mobilePinInfo": {
"lastMobilePinChange": "2017-07-13T11:22:06.099Z",
"mobilePinUsed": true,
"nextMobilePinChange": "2017-11-27T06:51:06.099Z"
},
"passInfo": {
"lastPassChange": "2017-07-21T09:25:06.099Z",
"nextPassChange": "2017-08-21T09:25:06.099Z",
"passwordUsed": true
},
"personId": 79683851815,
"pinInfo": {
"pinUsed": true
},
"registrationDate": "2017-01-07T16:51:06.100Z"
},
"contractInfo": {
"blocked": false,
"contractId": 79683851815,
"creationDate": "2017-01-07T16:51:06.100Z",
"features": [
...
],
"identificationInfo": [
{
"bankAlias": "QIWI",
"identificationLevel": "SIMPLE",
"passportExpired": false
}
]
},
"userInfo": {
"defaultPayCurrency": 643,
"defaultPaySource": 7,
"email": null,
"firstTxnId": 10807097143,
"language": "string",
"operator": "Beeline",
"phoneHash": "lgsco87234f0287",
"promoEnabled": null
}
}
Successful JSON-response has the following fields:
Field | Type | Description |
---|---|---|
authInfo | Object | Current authorization settings. The object may be missing, depending on the authInfoEnabled parameter in the request. |
authInfo.personId | Number | Wallet number |
authInfo.registrationDate | String | QIWI Wallet date/registration time (via website/mobile app, or otherwise) |
authInfo.boundEmail | String | E-mail linked to your QIWI wallet. If not, null |
authInfo.ip | String | IP address of the last user session |
authInfo.lastLoginDate | String | The date/time of the last session in QIWI Wallet service |
authInfo.mobilePinInfo | Object | PIN data of the mobile app |
mobilePinInfo.mobilePinUsed | Boolean | Flag of using a PIN-code (actually means that the mobile app is being used) |
mobilePinInfo.lastMobilePinChange | String | The date/time of the last time of the PIN change in the mobile app |
mobilePinInfo.nextMobilePinChange | String | The date/time of the next (planned) change of the PIN in the mobile app |
authInfo.passInfo | Object | Password usage data on the qiwi.com site |
passInfo.passwordUsed | Boolean | Flag of using password (actually means using the site qiwi.com) |
passInfo.lastPassChange | String | The date/time of the last password change on qiwi.com |
passInfo.nextPassChange | String | The date/time of the next (planned) password change on qiwi.com |
authInfo.pinInfo | Object | PIN usage data to the wallet app on the self-service kiosks |
pinInfo.pinUsed | Boolean | Flag of using a PIN for the terminal (actually means using the wallet app on the self-service kiosk) |
contractInfo | Object | Information about the wallet. The object may be missing, depending on the contractInfoEnabled parameter in the request. |
contractInfo.blocked | Boolean | Flag of wallet block |
contractInfo.contractId | Number | Wallet number |
contractInfo.creationDate | String | The date/time to create a wallet (via website/mobile app, either at first topup or otherwise) |
contractInfo.features | Array[Object] | Service info |
contractInfo.identificationInfo | Array[Object] | User's identification data |
identificationInfo[].bankAlias | String | String's acronym of the system, in which the user has received the identification::QIWI - QIWI Wallet. |
identificationInfo[].identificationLevel | String | Current level of the wallet identification. Possible values:ANONYMOUS - no identification;SIMPLE , VERIFIED - simplified identification;FULL - full identification. |
identificationInfo[].passportExpired | Boolean | Validity of passport data of the wallet' owner (true means that the passport data is invalid). |
userInfo | Object | Other user data. The object may be missing, depending on the userInfoEnabled parameter in the request. |
userInfo.defaultPayCurrency | Number(3) | Default wallet balance currency code (ISO-4217) |
userInfo.defaultPaySource | Number | Service info |
userInfo.email | String | User's e-mail |
userInfo.firstTxnId | Number | Identifier of the first transaction after registration |
userInfo.language | String | Service info |
userInfo.operator | String | Name of the mobile operator of the user's number |
userInfo.phoneHash | String | Service info |
userInfo.promoEnabled | String | Service info |
Identification API
Use methods of this API to identify and check identification status of your wallet in QIWI Wallet service. You need identification to get access to increased limits for balances and transactions.
Identification details (in Russian)
User identification
This request allows you to start the identification of your QIWI Wallet.
To obtain Main wallet status, you must provide the following data about the owner of the wallet:
- The name
- Series / Passport No.
- Date of birth
- TIN, SNILS or OMS policy number is optional.
To identify your wallet, you must send your name, series/passport number and date of birth. If the data has been verified, the answer will show your TIN and simplified wallet identification will be established. If the data has not been verified, the wallet remains in the status of "No Identification."
Request → POST
curl -X POST \
"https://edge.qiwi.com/identification/v1/persons/79111234567/identification" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"birthDate": "1998-02-11",
"firstName": "Иван",
"inn": "",
"lastName": "Иванов",
"middleName": "Иванович",
"oms": "",
"passport": "4400111222",
"snils": ""
}'
POST /identification/v1/persons/79111234567/identification HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Content-type: application/json
Host: edge.qiwi.com
{
"birthDate": "1998-02-11",
"firstName": "Иван",
"inn": "",
"lastName": "Иванов",
"middleName": "Иванович",
"oms": "",
"passport": "4400111222",
"snils": ""
}
import requests
def get_identification(api_access_token, my_login):
s = requests.Session()
s.headers['authorization'] = 'Bearer ' + api_access_token
res = s.get('https://edge.qiwi.com/identification/v1/persons/'+my_login+'/identification')
return res.json()
URL /identification/v1/persons/wallet/identification
- wallet - number of your QIWI wallet without + sign
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send in JSON body of the request:
Name | Type | Description |
---|---|---|
birthDate | String | Date of birth (in "YYYY-MM-DD" format) |
firstName | String | User's first name |
middleName | String | User's surname |
lastName | String | User's last name |
passport | String | Series / Passport No. (only digits) |
inn | String | User's TIN |
snils | String | User's SNILS |
oms | String | User's medical insurance number (OMS) |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"birthDate": "1996-03-18",
"firstName": "Иван",
"id": 79111234567,
"inn": "7710000001",
"lastName": "Иванов",
"middleName": "Иванович",
"oms": "",
"passport": "1122333000",
"snils": "",
"type": "VERIFIED"
}
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
print(get_identification(api_access_token, mylogin))
{'birthDate': '1984-01-09',
'firstName': 'Иванов',
'id': 79262111317,
'inn': 'xxxxxxx',
'lastName': 'Иванов',
'middleName': 'Иванович',
'oms': None,
'passport': 'xxxx xxxxxx',
'snils': None,
'type': 'FULL'}
Successful JSON response confirms wallet identification data:
Response field | Type | Description |
---|---|---|
id | Number | User's QIWI wallet number |
type | String | Current identification level of the wallet:SIMPLE - no identification, wallet status "MINIMAL".VERIFIED - wallet status "MAIN" (identification data has been successfully verified).FULL – the wallet already got "FULL" status by the provided personally verified name, passport and date of birth. |
birthDate | String | Date of birth |
firstName | String | User's first name |
middleName | String | User's surname |
lastName | String | User's last name |
passport | String | Series / Passport No. (only digits) |
inn | String | User's TIN. If the parameter is returned but not present in the original request, then the wallet identification is established |
snils | String | User's SNILS |
oms | String | User's medical insurance number (OMS) |
Identification data
Gets masked private data and identification status of your QIWI Wallet.
Request → GET
curl -X GET \
"https://edge.qiwi.com/identification/v1/persons/79111234567/identification" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /identification/v1/persons/79111234567/identification HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
URL /identification/v1/persons/wallet/identification
- wallet - your QIWI wallet number without + sign
URL /qw-limits/v1/persons/personId/actual-limits?parameter=value
- personId - your QIWI wallet number without + sign
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"birthDate": "1996-03-18",
"firstName": "Иван",
"id": 79111234567,
"inn": "77***01",
"lastName": "Иванов",
"middleName": "Иванович",
"oms": "",
"passport": "43***11",
"snils": "",
"type": "VERIFIED"
}
Successful JSON response contains masked data used for the wallet identification:
Response field | Type | Description |
---|---|---|
id | Number | User's QIWI wallet number |
type | String | Current identification level of the wallet:SIMPLE - no identification, status "MINIMAL".VERIFIED - status "MAIN" (identification data has been successfully verified).FULL – "FULL" status, the wallet already got full identification by the provided name, passport and date of birth. |
birthDate | String | Date of birth |
firstName | String | User's first name |
middleName | String | User's surname |
lastName | String | User's last name |
passport | String | Series / Passport No. (first and last two digits) |
inn | String | User's TIN (first and last two digits) |
snils | String | User's SNILS (first and last two digits) |
oms | String | User's medical insurance number (OMS) (first and last two digits) |
QIWI Wallet Limits API
Limit levels
By using this API, you can get current limits for operations in your QIWI wallet. Limits apply on accessible amount of the operations.
Request → GET
curl "https://edge.qiwi.com/qw-limits/v1/persons/79115221133/actual-limits?types%5B0%5D=TURNOVER" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /qw-limits/v1/persons/79115221133/actual-limits?types%5B0%5D=TURNOVER HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
def limits(login, api_access_token):
types = [ 'TURNOVER', 'REFILL', 'PAYMENTS_P2P', 'PAYMENTS_PROVIDER_INTERNATIONALS', 'PAYMENTS_PROVIDER_PAYOUT', 'WITHDRAW_CASH']
s = requests.Session()
s.headers['Accept']= 'application/json'
s.headers['Content-Type']= 'application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
parameters = {}
for i, type in enumerate(types):
parameters['types[' + str(i) + ']'] = type
b = s.get('https://edge.qiwi.com/qw-limits/v1/persons/' + login + '/actual-limits', params = parameters)
return b.json()
URL /qw-limits/v1/persons/personId/actual-limits?parameter=value
- personId - your QIWI wallet number without + sign
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send in the request path:
Name | Type | Description |
---|---|---|
types | Array[String] | A list of the types of operations that limits are requested for. Each type is numbered by an array element, starting from zero (types[0] , types[1] , etc.). Acceptable types of transactions:REFILL - balance in the accountTURNOVER - turnover per monthPAYMENTS_P2P - transfers to other wallets per monthPAYMENTS_PROVIDER_INTERNATIONALS - payments to foreign companies per monthPAYMENTS_PROVIDER_PAYOUT - transfers to bank accounts and cards, wallets of other systemsWITHDRAW_CASH - cash withdrawals per month.At least one type of operation must be specified. |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"limits":{
"RU" :[
{
"type": "TURNOVER",
"currency": "RUB",
"rest": 200.00,
"max": 40000.00,
"spent": 39800.00,
"interval": {
"dateFrom": "2019-11-01T:00:00",
"dateTill": "2019-12-01T00:00"
}
},
...
]
}
}
# wallet number like 79992223344
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# list of all limits
limits = limits(mylogin,api_access_token)['limits']['RU']
# turnover limit
turnoverInfo = [x for x in limits if x['type'] == 'TURNOVER']
turnoverLimit = turnoverInfo[0]['rest']
Successful JSON response contains an array of limits for your QIWI wallet operations:
Response field | Type | Description |
---|---|---|
limits | Object | Limits data |
limits[].'RU' | Array[Object] | An array of limits for operations |
type | String | Operation type where the limit is applied |
currency | String | Currency of the operation |
max | String | Value of the limit |
spent | String | Amount already spent in the operations |
rest | Boolean | The rest of the limit which can be used in the given period (see interval field) |
interval | Object | Details of the limit's period |
interval.dateFrom, interval.dateTill | String | Period's start and end, as YYYY-MM-DDTHH:MM:SStmz string |
Person-to-person transaction limit
The API returns the value of the person-to-person transaction number for the current month.
Request → GET
curl "https://edge.qiwi.com/qw-limits/v1/persons/79999999999/p2p-payment-count-limit" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /qw-limits/v1/persons/79999999999/p2p-payment-count-limit HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
# Number of person-to-person transactions
def get_p2p_payment_count(login, api_access_token):
s = requests.Session()
s.headers['Accept']= 'application/json'
s.headers['Content-Type']= 'application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
b = s.get('https://edge.qiwi.com/qw-limits/v1/persons/' + login + '/p2p-payment-count-limit')
return b.json()
URL /qw-limits/v1/persons/personId/p2p-payment-count-limit
- personId - your QIWI wallet number without "+"
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"p2pPaymentCountLimit": 1
}
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# P2p payment count for the current month
print(get_p2p_payment_count(api_access_token, mylogin))
{'p2pPaymentCountLimit': 1}
Successful JSON response contains an information of your person-to-person transactions:
Response field | Type | Description |
---|---|---|
p2pPaymentCountLimit | Number | Person-to-person transaction count per month |
Payments History API
Edit on GitHub
The API gives access to the history of transactions in your QIWI wallet.
List of payments
Provides a list of payments and top-ups of your wallet. You can use the filter by number, ID and date (date interval) of transactions.
Request → GET
Example 1. Last 10 payments
curl "https://edge.qiwi.com/payment-history/v2/persons/<wallet>/payments?rows=10" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
Example 2. Payments for 10.05.2017
curl "https://edge.qiwi.com/payment-history/v2/persons/<wallet>/payments?rows=50&startDate=2017-05-10T00%3A00%3A00%2B03%3A00&endDate=2017-05-10T23%3A59%3A59%2B03%3A00" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
Example 3. Continuing payments list (parameters nextTxnId=9103121 and nextTxnDate=2017-05-11T12:35:23+03:00 returned in the previous history request)
curl "https://edge.qiwi.com/payment-history/v2/persons/<wallet>/payments?rows=50&nextTxnId=9103121&nextTxnDate=2017-05-11T12%3A35%3A23%2B03%3A00" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
Example 4. Last 10 payments from the ruble account and from the linked card
GET /payment-history/v2/persons/<wallet>/payments?rows=10&operation=OUT&sources%5B0%5D=QW_RUB&sources%5B1%5D=CARD HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
Example 5. Payments for 10.05.2017 from the ruble account
GET /payment-history/v2/persons/<wallet>/payments?rows=50&sources%5B0%5D=QW_RUB&startDate=2017-05-10T00%3A00%3A00%2B03%3A00&endDate=2017-05-10T23%3A59%3A59%2B03%3A00 HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
Example 6. Continuing payments list for 10.05.2017 (see Example 2, parameters nextTxnId=9103121 и nextTxnDate=2017-05-11T12:35:23+03:00 returned)
GET /payment-history/v2/persons/<wallet>/payments?rows=50&nextTxnId=9103121&nextTxnDate=2017-05-11T12%3A35%3A23%2B03%3A00 HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
# Payments history - the most recent and next n payments
def payment_history_last(my_login, api_access_token, rows_num, next_TxnId, next_TxnDate):
s = requests.Session()
s.headers['authorization'] = 'Bearer ' + api_access_token
parameters = {'rows': rows_num, 'nextTxnId': next_TxnId, 'nextTxnDate': next_TxnDate}
h = s.get('https://edge.qiwi.com/payment-history/v2/persons/' + my_login + '/payments', params = parameters)
return h.json()
URL /payment-history/v2/persons/wallet/payments?parameter=value
- wallet - your QIWI wallet number without + sign
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
These are transmitted in the query path:
Name | Type | Description |
---|---|---|
rows | Integer | The number of payments in response to break down the report into chunks. It must be from 1 to 50. The request returns a specified number of payments in reverse chronological order, starting from the current date or date in the startDate option. Required |
operation | String | The type of operations in the report, for selection. Acceptable values:ALL - all transactions, IN - only top-ups, OUT - only payments, QIWI_CARD - only payments from QIWI cards (QVC, QVP). By default, ALL is used |
sources | Array[String] | A list of payment sources for the filter. Each source is numbered from scratch (sources[0] , sources[1] etc). Acceptable values: QW_RUB - ruble account of your QIWI wallet, QW_USD - USD account of your QIWI wallet, QW_EUR - euro account of your QIWI wallet, CARD - cards linked to the wallet and other credit cards, MK - the corresponding account on the mobile operator. If not specified, all sources are considering |
startDate | DateTime URL-encoded | The initial date for the search for payments. It is only used with endDate . The maximum allowable interval between startDate and endDate is 90 calendar days. By default, equal to the daily shift from the current date to Moscow time. The date can be specified in any time zone TZD (in YYYY-MM-DD'T'hh:mm:ssTZD format), but it must coincide with the time zone in the endDate parameter. Timezone designation: +hh:mm or -hh:mm (time shift from GMT). |
endDate | DateTime URL-encoded | The final date for the search for payments. It is only used with startDate . The maximum allowable interval between startDate and endDate is 90 calendar days. By default, equal to current date/time in Moscow time. The date can be specified in any time zone TZD (in YYYY-MM-DD'T'hh:mm:ssTZD format), but it must coincide with the time zone in the startDate parameter. Timezone designation: +hh:mm or -hh:mm (time shift from GMT). |
nextTxnDate | DateTime URL-encoded | The transaction date to start the report (should be equal to nextTxnDate in the previous report). Used only with nextTxnId |
nextTxnId | Long | The transaction number to start the report (should be equal to nextTxnId in the previous report). Used only with nextTxnDate |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{"data":
[{
"txnId":9309,
"personId":79112223344,
"date":"2017-01-21T11:41:07+03:00",
"errorCode":0,
"error":null,
"status":"SUCCESS",
"type":"OUT",
"statusText":"Успешно",
"trmTxnId":"1489826461807",
"account":"0003***",
"sum":{
"amount":70,
"currency":643
},
"commission":{
"amount":0,
"currency":643
},
"total":{
"amount":70,
"currency":643
},
"provider":{
...
},
"source": {},
"comment":"",
"currencyRate":1
}],
"nextTxnId":9001,
"nextTxnDate":"2017-01-31T15:24:10+03:00"
}
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# last 20 payments
lastPayments = payment_history_last(mylogin, api_access_token, '5','','')
# date and time of the next payment (to use in the next request)
nextTxnDate = lastPayments['nextTxnDate']
# transaction id of the next payment (to use in the next request)
nextTxnId = lastPayments['nextTxnId']
# the most recent and next n payments
orderedPayments = payment_history_last(mylogin, api_access_token, '5', nextTxnId, nextTxnDate)
Successful JSON-response contains a list of payments corresponding to the request's filter:
Field | Type | Description |
---|---|---|
data | Array[Object] | A list of PaymentHistoryItem objects. Number of objects in the list is less than or equals to rows value from the request |
nextTxnId | Number(Integer) | Next transaction ID, in the complete list of your transactions |
nextTxnDate | DateTime | Next transaction date/time, in the complete list of your transactions, Moscow time (in YYYY-MM-DD'T'hh:mm:ss+03:00 ) |
Statistics
Provides aggregate statistics on the amount of payments for a given period.
Request → GET
curl "https://edge.qiwi.com/payment-history/v2/persons/<wallet>/payments/total?startDate=2017-03-01T00%3A00%3A00%2B03%3A00&endDate=2017-03-31T11%3A44%3A15%2B03%3A00" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /payment-history/v2/persons/<wallet>/payments/total?startDate=2017-03-01T00%3A00%3A00%2B03%3A00&endDate=2017-03-31T11%3A44%3A15%2B03%3A00 HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
# Sum of payments for a range of dates
def payment_history_summ_dates(my_login, api_access_token, start_Date, end_Date):
s = requests.Session()
s.headers['authorization'] = 'Bearer ' + api_access_token
parameters = {'startDate': start_Date,'endDate': end_Date}
h = s.get('https://edge.qiwi.com/payment-history/v2/persons/' + my_login + '/payments/total', params = parameters)
return h.json()
URL /payment-history/v2/persons/wallet/payments/total?parameter=value
- wallet - the number of your QIWI wallet without + sign
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send them in the query path:
Name | Type | Description |
---|---|---|
startDate | DateTime URL-encoded | Start date of the period, in any time zone TZD (date format YYYY-MM-DD'T'hh:mm:ssTZD ). Time zone must coincide with endDate time zone. Designation TZD : +hh:mm or -hh:mm (time shift from GMT). Required |
endDate | DateTime URL-encoded | Final date of th period, in any time zone TZD (date format YYYY-MM-DD'T'hh:mm:ssTZD ). Time zone must coincide with startDate time zone. Designation TZD : +hh:mm or -hh:mm (time shift from GMT). Required |
operation | String | Operations to take into account when accumulating statistics. Possible values:ALL - all operations, IN - only top-ups, OUT - only payments, QIWI_CARD - only payments from QIWI cards (QVC, QVP). Default value is ALL . |
sources | Array[String] | Payment sources to filter data. Each source is enumerated starting from zero (sources[0] , sources[1] and so on). Possible values of each source: QW_RUB - ruble QIWI Wallet account, QW_USD - USD QIWI Wallet account, QW_EUR - euro QIWI Wallet account, CARD - credit cards, both linked to QIWI Wallet and others, MK - mobile operator account. If not specified, all sources are collected. |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"incomingTotal":[
{
"amount":3500,
"currency":643
}
],
"outgoingTotal":[
{
"amount":3497.5,
"currency":643
}
]
}
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# Payments amount from April 12 till July 11
print(payment_history_summ_dates(mylogin, api_access_token, '2019-04-12T00:00:00Z','2019-07-11T23:59:59Z'))
{'incomingTotal': [{'amount': 3.33, 'currency': 840},
{'amount': 3481, 'currency': 643}],
'outgoingTotal': [{'amount': 3989.98, 'currency': 643},
{'amount': 3.33, 'currency': 840}]}
Successful JSON-response contains statistics data for a specified period:
Field | Type | Description |
---|---|---|
incomingTotal | Array[Object] | Array of total amounts of incoming payments (top-up payments) separated by payment's currency |
incomingTotal[].amount | Number(Decimal) | Top-ups amount for the period |
incomingTotal[].currency | Number(3) | Currency of the operations (ISO-4217) |
outgoingTotal | Array[Object] | Array of total amounts of payments separated by payment's currency |
outgoingTotal[].amount | Number(Decimal) | Payments amount for the period |
outgoingTotal[].currency | Number(3) | Currency of the operations (ISO-4217) |
Transaction details
Returns details on a specific transaction from your payments history.
Request → GET
curl "https://edge.qiwi.com/payment-history/v2/transactions/9112223344" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /payment-history/v2/transactions/9112223344 HTTP/1.1
Accept: application/json
Authorization: Bearer YUu2qw048gtdsvlk3iu
Host: edge.qiwi.com
import requests
# Transaction details
def payment_history_transaction(api_access_token, transaction_id, transaction_type):
s = requests.Session()
s.headers['authorization'] = 'Bearer ' + api_access_token
parameters = {'type': transaction_type} # transaction_type 'IN' 'OUT'
h = s.get('https://edge.qiwi.com/payment-history/v1/transactions/'+transaction_id, params = parameters)
return h.json()
URL /payment-history/v2/transactions/transactionId?type=value
- transactionId - transaction ID from Payments history report (txnId field of Transaction object)
- type - transaction type from Payments history report (type field of Transaction object). This is optional parameter
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"txnId": 11233344692,
"personId": 79161122331,
"date": "2017-08-30T14:38:09+03:00",
"errorCode": 0,
"error": null,
"status": "WAITING",
"type": "OUT",
"statusText": "Запрос обрабатывается",
"trmTxnId": "11233344691",
"account": "15040930424823121081",
"sum": {
"amount": 1,
"currency": 643
},
"commission": {
"amount": 0,
"currency": 643
},
"total": {
"amount": 1,
"currency": 643
},
"provider": {
"id": 1,
"shortName": "MTS",
"longName": "MTS",
"logoUrl": null,
"description": null,
"keys": null,
"siteUrl": null,
"extras": []
},
"source": {
"id": 7,
"shortName": "QIWI Wallet",
"longName": "QIWI Wallet",
"logoUrl": null,
"description": null,
"keys": "мобильный кошелек, кошелек, перевести деньги, личный кабинет, отправить деньги, перевод между пользователями",
"siteUrl": null,
"extras": []
},
"comment": "",
"currencyRate": 1,
"paymentExtras": [],
"serviceExtras": {},
"view": {},
"features": {
"chequeReady": false,
"bankDocumentAvailable": false,
"bankDocumentReady": false,
"repeatPaymentEnabled": false,
"favoritePaymentEnabled": false,
"regularPaymentEnabled": false
}
}
# wallet number like 79992223344
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# Transaction ID 11181101215 details
transactionInfo = payment_history_transaction(api_access_token, '11181101215', 'OUT')
# Transaction number 5 details
lastPayments = payment_history_last(mylogin, api_access_token, '20','','')
last_txn_id = lastPayments['data'][5]['txnId']
last_txn_type = lastPayments['data'][5]['type']
transactionInfo = payment_history_transaction(api_access_token, str(last_txn_id), last_txn_type)
Successful JSON-response contains Transaction object.
Payment receipt
Returns electronic receipt for a certain transaction in PDF/JPEG format, either as binary file or via e-mail to specified address.
Receipt file
Request → GET
curl "https://edge.qiwi.com/payment-history/v1/transactions/9112223344/cheque/file?type=IN&format=PDF" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /payment-history/v1/transactions/9112223344/cheque/file?type=IN&format=PDF HTTP/1.1
Accept: application/json
Authorization: Bearer YUu2qw048gtdsvlk3iu
Host: edge.qiwi.com
import requests
# Get receipt text in file
def payment_history_cheque_file(transaction_id, transaction_type, filename, api_access_token):
s = requests.Session()
s.headers['Accept'] ='application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
parameters = {'type': transaction_type,'format': 'PDF'}
h = s.get('https://edge.qiwi.com/payment-history/v1/transactions/'+transaction_id+'/cheque/file', params=parameters)
h.status_code
with open(filename + '.pdf', 'wb') as f:
f.write(h.content)
URL /payment-history/v1/transactions/transactionId/cheque/file?type=value&format=value
- transactionId - transaction ID from Payments history report (txnId field in Transaction object)
- type - transaction type from Payments history report (type field in Transaction object)
- format - file type for receipt export. Possible values: JPEG, PDF
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
[
""
]
Successful JSON-response contains binary file.
Receipt sending
Request → POST
curl -X POST \
"https://edge.qiwi.com/payment-history/v1/transactions/9112223344/cheque/send?type=IN" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{"email": "my@example.com"}'
POST /payment-history/v1/transactions/9112223344/cheque/send?type=IN HTTP/1.1
Accept: application/json
Authorization: Bearer YUu2qw048gtdsvlk3iu
Content-type: application/json
Host: edge.qiwi.com
{"email": "my@example.com"}
import requests
# Send receipt to email
def payment_history_cheque_send(transaction_id, transaction_type, email, api_access_token):
s = requests.Session()
s.headers['content-type'] ='application/json'
s.headers['Accept'] ='application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
postjson = {'email':email}
h = s.post('https://edge.qiwi.com/payment-history/v1/transactions/' + transaction_id + '/cheque/send?type=' + transaction_type, json = postjson)
h.status_code
URL /payment-history/v1/transactions/transactionId/cheque/send?type=value
- transactionId - transaction ID from Payments history report (txnId field in Transaction object)
- type - transaction type from Payments history report (type field in Transaction object)
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameter
Send this parameter in JSON body of the request:
Name | Type | Description |
---|---|---|
String | Email address |
Response ←
HTTP/1.1 201 Created
# wallet number like 79992223344
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
lastPayments = payment_history_last(mylogin, api_access_token, '20','','')
last_txn_id = lastPayments['data'][5]['txnId']
last_txn_type = lastPayments['data'][5]['type']
# Send receipt to email
payment_history_cheque_send(str(last_txn_id), last_txn_type, 'mmd@yandex.ru', api_access_token)
Successful JSON-response contains HTTP result code of file sending operation.
API data models
PaymentHistoryItem class
Object contains information about existing QIWI Wallet payment.
Name | Type | Description |
---|---|---|
txnId | Integer | Transaction ID in QIWI Wallet processing |
personId | Integer | Wallet number |
date | DateTime | For payments history reports - Payment date/time, in the request time zone (see startDate parameter). Date format YYYY-MM-DD'T'hh:mm:ss+03:00 For transaction details - Payment date/time, in Moscow time zone (date format: YYYY-MM-DD'T'hh:mm:ss+03:00 ) |
errorCode | Number(Integer) | Payment error code |
error | String | Error description |
type | String | Payment type. Possible values:IN - top-up, OUT - payment, QIWI_CARD - payment from QIWI card (QVC, QVP). |
status | String | Payment status. Possible values:WAITING - payment is processing, SUCCESS - successful payment, ERROR - payment error. |
statusText | String | Text description of the status |
trmTxnId | String | Transaction's client ID (assigned on the client device) |
account | String | For payments, recipient's identifier (masked card number, phone number, account number etc.). For top-ups, sender's or terminal's identifier, or top-up agent name |
sum | Object | Payment's amount data. |
sum.amount | Number(Decimal) | amount, |
sum.currency | Number(3) | currency (ISO-4217) |
commission | Object | Payment's commission data |
commission.amount | Number(Decimal) | amount, |
commission.currency | Number(3) | currency (ISO-4217) |
total | Object | Total amount of transaction. |
total.amount | Number(Decimal) | amount, it is sum.amount plus commission.amount , |
total.currency | Number(3) | currency (ISO-4217) |
provider | Object | Provider's data |
provider.id | Integer | Provider ID in QIWI Wallet system, |
provider.shortName | String | Provider's short name, |
provider.longName | String | Provider's extended name, |
provider.logoUrl | String | Provider's logo URL, |
provider.description | String | Provider's description (in HTML), |
provider.keys | String | Provider's keywords list, |
provider.siteUrl | String | Provider's site |
comment | String | Comment to the payment |
currencyRate | Number(Decimal) | Currency exchange rate (if applied to transaction) |
Transaction class
Object contains information about existing QIWI Wallet transaction.
Name | Type | Description |
---|---|---|
txnId | Integer | Transaction ID in QIWI Wallet processing |
personId | Integer | Wallet number |
date | DateTime | For payments history reports - Payment date/time, in the request time zone (see startDate parameter). Date format YYYY-MM-DD'T'hh:mm:ss+03:00 For transaction details - Payment date/time, in Moscow time zone (date format: YYYY-MM-DD'T'hh:mm:ss+03:00 ) |
errorCode | Number(Integer) | Payment error code |
error | String | Error description |
type | String | Payment type. Possible values:IN - top-up, OUT - payment, QIWI_CARD - payment from QIWI card (QVC, QVP). |
status | String | Payment status. Possible values:WAITING - payment is processing, SUCCESS - successful payment, ERROR - payment error. |
statusText | String | Text description of the status |
trmTxnId | String | Transaction's client ID (assigned on the client device) |
account | String | For payments, recipient's identifier (masked card number, phone number, account number etc.). For top-ups, sender's or terminal's identifier, or top-up agent name |
sum | Object | Payment's amount data. |
sum.amount | Number(Decimal) | amount, |
sum.currency | Number(3) | currency (ISO-4217) |
commission | Object | Payment's commission data |
commission.amount | Number(Decimal) | amount, |
commission.currency | Number(3) | currency (ISO-4217) |
total | Object | Total amount of transaction. |
total.amount | Number(Decimal) | amount, it is sum.amount plus commission.amount , |
total.currency | Number(3) | currency (ISO-4217) |
provider | Object | Provider's data |
provider.id | Integer | Provider ID in QIWI Wallet system, |
provider.shortName | String | Provider's short name, |
provider.longName | String | Provider's extended name, |
provider.logoUrl | String | Provider's logo URL, |
provider.description | String | Provider's description (in HTML), |
provider.keys | String | Provider's keywords list, |
provider.siteUrl | String | Provider's site |
comment | String | Comment to the payment |
currencyRate | Number(Decimal) | Currency exchange rate (if applied to transaction) |
paymentExtras | Array of Object | Service information |
features | Object | Set of special fields |
features.chequeReady | Boolean | Special field |
features.bankDocumentReady | Boolean | Special field |
features.bankDocumentAvailable | Boolean | Special field |
features.repeatPaymentEnabled | Boolean | Special field |
features.favoritePaymentEnabled | Boolean | Special field |
features.regularPaymentEnabled | Boolean | Special field |
features.chatAvailable | Boolean | Special field |
features.greetingCardAttached | Boolean | Special field |
serviceExtras | Object | Служебная информация |
view | Object | Служебная информация |
Wallet Balances API
Edit on GitHub
API provides methods to control balances of your QIWI wallet.
List of balances
Provides current balances of your QIWI Wallet.
Request → GET
curl "https://edge.qiwi.com/funding-sources/v2/persons/<wallet>/accounts" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /funding-sources/v2/persons/<wallet>/accounts HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
# QIWI Wallet balances
def balance(login, api_access_token):
s = requests.Session()
s.headers['Accept']= 'application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
b = s.get('https://edge.qiwi.com/funding-sources/v2/persons/' + login + '/accounts')
return b.json()
URL /funding-sources/v2/persons/personId/accounts
- personId - your wallet number (without + sign)
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"accounts": [
{
"alias": "mc_beeline_rub",
"fsAlias": "qb_mc_beeline",
"bankAlias": "QIWI",
"title": "MC",
"type": {
"id": "MC",
"title": "Счет мобильного кошелька"
},
"hasBalance": false,
"balance": null,
"currency": 643
},
{
"alias": "qw_wallet_rub",
"fsAlias": "qb_wallet",
"bankAlias": "QIWI",
"title": "WALLET",
"type": {
"id": "WALLET",
"title": "QIWI Wallet"
},
"hasBalance": true,
"balance": {
"amount": 8.74,
"currency": 643
},
"currency": 643
}
]
}
# wallet number as 79992223344
mylogin = '79999999999'
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# All balances
balances = balance(mylogin,api_access_token)['accounts']
# Ruble account balance
rubAlias = [x for x in balances if x['alias'] == 'qw_wallet_rub']
rubBalance = rubAlias[0]['balance']['amount']
Repeated request when you got empty "balance" object and "hasBalance": true in response
GET /funding-sources/v2/persons/79115221133/accounts?timeout=1000&alias=qw_wallet_rub HTTP/1.1
Accept: application/json
Authorization: Bearer YUu2qw048gtdsvlk3iu
Host: edge.qiwi.com
Successful response is JSON array of all active balances of your QIWI wallet used for payment funding:
Response field | Type | Description |
---|---|---|
accounts | Array[Object] | Array of balances |
accounts[].alias | String | User balance alias |
accounts[].fsAlias | String | Bank account alias |
accounts[].bankAlias | String | Bank alias |
accounts[].title | String | Wallet account name |
accounts[].hasBalance | Boolean | Flag of actual QIWI Wallet balance (not a linked card or cell phone balance or something like that) |
accounts[].currency | Number(3) | Currency of the balance (ISO-4217). Only balances in following currencies are returned: 643 - Russian ruble, 840 - USD, 978 - Euro |
accounts[].type | Object | Account information |
type.id, type.title | String | Account title |
accounts[].balance | Object | Balance data. If null is returned and accounts[].hasBalance is true , repeat the request with additional parameters:timeout=1000 and alias="accounts[].alias" (alias of that balance) |
balance.amount | Number | Текущий баланс данного счета |
balance.currency | Number(3) | Код валюты баланса (ISO-4217) |
Creating balance
Creates a new account and its balance in your QIWI wallet. List of account types which you can create is provided by other request.
Request → POST
curl -X POST \
"https://edge.qiwi.com/funding-sources/v2/persons/<wallet/accounts" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{ "alias": "qw_wallet_eur"}'
POST /funding-sources/v2/persons/<wallet>/accounts HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Content-type: application/json
Host: edge.qiwi.com
{ "alias": "qw_wallet_eur" }
URL /funding-sources/v2/persons/personId/accounts
- personId - your wallet number without + sign
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
In JSON body of the request:
Name | Type | Description |
---|---|---|
alias | String | Alias of the new account (taken from Available accounts) |
Response ←
HTTP/1.1 201 Created
Successful response contains HTTP code 201
.
Available accounts
Provides all possible account aliases for your QIWI wallet.
Request → GET
curl -X GET \
"https://edge.qiwi.com/funding-sources/v2/persons/<wallet>/accounts/offer" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /funding-sources/v2/persons/<wallet>/accounts/offer HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
URL /funding-sources/v2/persons/personId/accounts/offer
- personId - your wallet number without + sign
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{ { "alias": "qw_wallet_eur", "currency": 978 }, {} }
Successful JSON response contains a list of accounts available for creation:
Response field | Type | Description |
---|---|---|
{} | Object | List of accounts |
Object.alias | String | Alias of the account |
Object.currency | Number(3) | Account's currency code (ISO-4217) |
Default balance
Sets up default account in your QIWI wallet for funding all payments. The account must be in the list of available accounts
Request → PATCH
curl -X PATCH \
"https://edge.qiwi.com/funding-sources/v2/persons/<wallet>/accounts/qw_wallet_usd" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{ "defaultAccount": true }'
PATCH /funding-sources/v2/persons/<wallet>/accounts/qw_wallet_usd HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Content-type: application/json
Host: edge.qiwi.com
{ "defaultAccount": true }
URL /funding-sources/v2/persons/personId/accounts/accountAlias
- personId - your wallet number without + sign
- accountAlias - account's alias in the wallet, from a list (see parameter accounts[].alias in response)
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Parameter in JSON body:
Name | Type | Description |
---|---|---|
defaultAccount | Boolean | Flag of default account |
Response ←
HTTP/1.1 204 Modified
Successful response has HTTP code 204
.
Payments API
Edit on GitHub
API provides access to payments for service providers available in QIWI Wallet services.
Payment form auto-filling
URL-link
https://qiwi.com/payment/form/{provider-id}?{parameter}={value}
opens auto-filled payment form on qiwi.com site for the given provider.
If a user opens the link on a smartphone:
- and QIWI Wallet app is installed, then the app with filled payment form opens after entering access code;
- and there is no QIWI Wallet app on the smartphone, then the link is opened in a browser or using WebView.
Link example (click to see the form)
If you don't want to show your wallet number, use wallet nickname:
Link example for nickname transfer (click to see the form)
To get payments to your QIWI Wallet, you can use also P2P-form.
Request → GET
GET /payment/form/99?account=79991112233&sum=1.1&comment=test123¤cy=643 HTTP/1.1
Host: qiwi.com
URL https://qiwi.com/payment/form/{ID}?{parameter}={value}
Where:
ID — provider's identifier. Only providers with payment requisites limited to fields.account
are accepted. Possible values:
99
— QIWI Wallet transfer.99999
— QIWI Wallet nickname transfer.- Identifiers for mobile phone top-up.
1963
— Visa card transfer (issued by only Russian banks).21013
— MasterCard card transfer (issued by only Russian banks).31652
— MIR national payment system card transfer.22351
— QIWI Virtual card transfer.- Identifiers for payments to other services.
Parameters
Parameters in URL query to fill the form fields:
Name | Type | Description | Form field |
---|---|---|---|
sum | Decimal, 10.15 |
Payment amount (fractional part should be rounded to two digits). If absent, the Amount field on the form will be empty. The number not greater than 99,999.00 (payment amount limit) | Amount |
currency | Constant string, 643 |
Payment currency code. Required if you send the payment amount in the link | - |
comment | URL-encoded string | Payment comment. Use it only for ID=99 | Comment to the transfer |
account | URL-encoded string | See format of fields.account parameter of the provider in the corresponding payment request. Examples:for provider 99 - recipient's wallet number;for mobile network operators - phone number for top-up (without international prefix); for card transfer - recipient's card number without spaces; for other providers - user's identifier; for provider 99999 – nickname or number of the wallet (determined by accountType parameter) |
Wallet number, Phone number, User ID |
blocked | Array[String] | Name of blocked (inactive) form field. The user will not be able to change this field unless they change it in the browser address bar.. Each parameter corresponds to respective form field and should be numbered starting from zero (blocked[0] , blocked[1] , and so on). If absent, user can change all form fields. The parameter is applied only if the link is opened in a browser. Possible values:sum - Payment amount field, account - Phone number/Account number field,comment - Comment field.Example (for payment amount field): blocked[0]=sum |
- |
accountType | URL-encoded string | Use only for ID=99999. The value determines transfer to QIWI wallet by nickname or wallet number.phone - for transfer to wallet numbernickname - for transfer to wallet nickname. If you don't want to show your wallet number on the form, use this value. |
- |
Commission rates
Returns total commission amount for the payment by the given payment requisites.
Request → POST
curl -X POST \
'https://edge.qiwi.com/sinap/providers/99/onlineCommission' \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"account":"380995238345",
"paymentMethod":{
"type":"Account",
"accountId":"643"
},
"purchaseTotals":{
"total":{
"amount":10,
"currency":"643"
}
}
}'
POST /sinap/providers/99/onlineCommission HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"account":"380995238345",
"paymentMethod":{
"type":"Account",
"accountId":"643"
},
"purchaseTotals":{
"total":{
"amount":10,
"currency":"643"
}
}
}
import requests
# Тарифные комиссии
def get_commission(api_access_token, to_account, prv_id, sum_pay):
s = requests.Session()
s.headers = {'content-type': 'application/json'}
s.headers['authorization'] = 'Bearer ' + api_access_token
postjson = {"account":"","paymentMethod":{"type":"Account","accountId":"643"}, "purchaseTotals":{"total":{"amount":"","currency":"643"}}}
postjson['account'] = to_account
postjson['purchaseTotals']['total']['amount'] = sum_pay
c_online = s.post('https://edge.qiwi.com/sinap/providers/'+prv_id+'/onlineCommission',json = postjson)
return c_online.json()['qwCommission']['amount']
URL /sinap/providers/ID/onlineCommission
Where:
ID — provider's identifier. Possible values:
- 99 — QIWI Wallet transfer.
- 1717 — Payment by bank requisites to commercial organization.
- Providers of bank wire transfer.
You can also search for a required identifier through API by keywords.
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Required parameters in JSON body:
Name | Type | Description |
---|---|---|
account | String | User's identifier (phone number, card/account number, and other entity depending on provider) |
paymentMethod | Object | Object defining payment processing by QIWI Wallet. Includes the following parameters: |
paymentMethod.type | String | Payment method, Account only |
paymentMethod.accountId | String | QIWI Wallet account identifier, 643 only. |
purchaseTotals | Object | Object with payment requisites |
purchaseTotals.total | Object | Payment amount data: |
total.amount | Number | Amount (rubles and kopeks, divided by . ). Positive number, rounded down to 2 decimals. If you send more decimals, value will be rounded down to kopeks. |
total.currency | String | Currency (643 only, that is rubles) |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"providerId": 99,
...
"qwCommission": {
"amount": 10.01,
"currency": "643"
}
}
api_access_token = '975efd8e8376xxxb95fa7cb213xxx04'
# QIWI wallet transfer commission
print(get_commission(api_access_token,'+380000000000','99',5000))
# Card transfer commission
print(get_commission(api_access_token,'4890xxxxxxxx1698','22351',1000))
Commission rate is returned in qwCommission.amount
field of the JSON response.
QIWI wallet transfer
Request → POST
curl -X POST \
'https://edge.qiwi.com/sinap/api/v2/terms/99/payments' \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"11111111111111",
"sum": {
"amount":100,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"comment":"test",
"fields": {
"account":"+79121112233"
}
}'
POST /sinap/api/v2/terms/99/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"11111111111111",
"sum": {
"amount":100.50,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"comment":"test",
"fields": {
"account":"+79121112233"
}
}
import requests
import time
# QIWI wallet transfer
def send_p2p(api_access_token, to_qw, comment, sum_p2p):
s = requests.Session()
s.headers = {'content-type': 'application/json'}
s.headers['authorization'] = 'Bearer ' + api_access_token
s.headers['User-Agent'] = 'Android v3.2.0 MKT'
s.headers['Accept'] = 'application/json'
postjson = {"id":"","sum":{"amount":"","currency":""},"paymentMethod":{"type":"Account","accountId":"643"}, "comment":"'+comment+'","fields":{"account":""}}
postjson['id'] = str(int(time.time() * 1000))
postjson['sum']['amount'] = sum_p2p
postjson['sum']['currency'] = '643'
postjson['fields']['account'] = to_qw
res = s.post('https://edge.qiwi.com/sinap/api/v2/terms/99/payments',json = postjson)
return res.json()
URL /sinap/api/v2/terms/99/payments
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON object Payment in the request's body. Payment requisites in fields
object:
Name | Type | Description |
---|---|---|
fields.account | String | Required. Wallet number of the recipient |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "150217833198900",
"terms": "99",
"fields": {
"account": "79121238345"
},
"sum": {
"amount": 100,
"currency": "643"
},
"transaction": {
"id": "11155897070",
"state": {
"code": "Accepted"
}
},
"source": "account_643",
"comment": "test"
}
print(send_p2p(mylogin,api_access_token,'+79261112233','comment',99.01))
{'comment': 'comment',
'fields': {'account': '+79261112233'},
'id': '1514296828893',
'source': 'account_643',
'sum': {'amount': 99.01, 'currency': '643'},
'terms': '99',
'transaction': {'id': '11982501857', 'state': {'code': 'Accepted'}}}
Successful response contains JSON-object PaymentInfo with accepted payment data.
QIWI wallet nickname
Request → GET
curl -X GET \
"https://edge.qiwi.com/qw-nicknames/v1/persons/79111234567/nickname" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /qw-nicknames/v1/persons/79111234567/nickname HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
URL /qw-nicknames/v1/persons/wallet/nickname
- wallet - your wallet number without + sign
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"canChange": true,
"canUse": true,
"description": "",
"nickname": "NICKNAME"
}
Successful response contains nickname of your wallet in JSON field nickname
.
Conversion
Transfers funds to currency account in QIWI wallet with conversion from your QIWI wallet ruble account. Two transactions are created: conversion between accounts of your QIWI wallet, and transfer to another wallet. You can get currency rates from another API method.
Request → POST
curl -X POST \
'https://edge.qiwi.com/sinap/api/v2/terms/1099/payments' \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"11111111111111",
"sum": {
"amount":100,
"currency":"398"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"comment":"test",
"fields": {
"account":"+79121112233"
}
}'
POST /sinap/api/v2/terms/1099/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"11111111111111",
"sum": {
"amount":10.00,
"currency":"398"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"comment":"test",
"fields": {
"account":"+79121112233"
}
}
import requests
import time
# Conversion in QIWI wallet (currency as currency integer code as String)
def exchange(api_access_token, sum_exchange, currency, to_qw):
s = requests.Session()
currencies = ['398', '840', '978']
if currency not in currencies:
print('This currency not available')
return
s.headers = {'content-type': 'application/json'}
s.headers['authorization'] = 'Bearer ' + api_access_token
s.headers['User-Agent'] = 'Android v3.2.0 MKT'
s.headers['Accept'] = 'application/json'
postjson = {"id":"","sum":{"amount":"","currency":""},"paymentMethod":{"type":"Account","accountId":"643"}, "comment":"'+comment+'","fields":{"account":""}}
postjson['id'] = str(int(time.time() * 1000))
postjson['sum']['amount'] = sum_exchange
postjson['sum']['currency'] = currency
postjson['fields']['account'] = to_qw
res = s.post('https://edge.qiwi.com/sinap/api/v2/terms/1099/payments',json = postjson)
return res.json()
URL /sinap/api/v2/terms/1099/payments
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON object Payment in the request's body. Payment requisites in fields
object:
Name | Type | Description |
---|---|---|
fields.account | String | Required. Wallet number for the conversion |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "150217833198900",
"terms": "99",
"fields": {
"account": "79121238345"
},
"sum": {
"amount": 100,
"currency": "398"
},
"transaction": {
"id": "11155897070",
"state": {
"code": "Accepted"
}
},
"source": "account_643",
"comment": "test"
}
Successful response contains JSON-object PaymentInfo with accepted payment data.
Currency rates
Returns current QIWI Bank currency rates and cross-rates.
Request → GET
curl "https://edge.qiwi.com/sinap/crossRates" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /sinap/crossRates HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
# Currencies rate (currency pair codes in String)
def exchange(api_access_token, currency_to, currency_from):
s = requests.Session()
s.headers = {'content-type': 'application/json'}
s.headers['authorization'] = 'Bearer ' + api_access_token
s.headers['User-Agent'] = 'Android v3.2.0 MKT'
s.headers['Accept'] = 'application/json'
res = s.get('https://edge.qiwi.com/sinap/crossRates')
# all rates
rates = res.json()['result']
# requested rate
rate = [x for x in rates if x['from'] == currency_from and x['to'] == currency_to]
if (len(rate) == 0):
print('No rate for this currencies!')
return
else:
return rate[0]['rate']
URL /sinap/crossRates
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"result": [
{
"set": "General",
"from": "398",
"to": "643",
"rate": 6.22665
},
{
"set": "General",
"from": "398",
"to": "756",
"rate": 412.0174305
},
...,
{
"set": "General",
"from": "980",
"to": "978",
"rate": 31.4680914
}
]
}
Successful response contains JSON array of currency rates in result
field. An element of the list corresponds to currency pair:
Response field | Type | Description |
---|---|---|
from | String | Base currency |
to | String | Quote currency |
rate | Number | Rate |
Mobile network payment
Request → POST
curl -X POST \
"https://edge.qiwi.com/sinap/api/v2/terms/1/payments" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"11111111111111",
"sum": {
"amount":100,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account":"9161112233"
}
}'
POST /sinap/api/v2/terms/1/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account":"9161112233"
}
}
import requests
import time
# Cell phone top-up
def send_mobile(api_access_token, prv_id, to_account, comment, sum_pay):
s = requests.Session()
s.headers['Accept'] = 'application/json'
s.headers['Content-Type'] = 'application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
postjson = {"id":"","sum": {"amount":"","currency":"643"},"paymentMethod": {"type":"Account","accountId":"643"},"comment":"","fields": {"account":""}}
postjson['id'] = str(int(time.time() * 1000))
postjson['sum']['amount'] = sum_pay
postjson['fields']['account'] = to_account
postjson['comment'] = comment
res = s.post('https://edge.qiwi.com/sinap/api/v2/terms/'+prv_id+'/payments', json = postjson)
return res.json()
URL /sinap/api/v2/terms/ID/payments
- ID - QIWI provider identifier. How to get provider ID
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON object Payment in the request's body. Payment requisites in fields
object:
Name | Type | Description |
---|---|---|
fields.account | String | Cell phone number to top-up (without 8 prefix) |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "21131343",
"terms": "1",
"fields": {
"account": "9161112233"
},
"sum": {
"amount": 1000,
"currency": "643"
},
"source": "account_643",
"transaction": {
"id": "4969142201",
"state": {
"code": "Accepted"
}
}
}
send_mobile(api_access_token,'2','9670058909','123','1')
Successful response contains JSON-object PaymentInfo with accepted payment data.
Card money transfer
Transfers money to Visa, MasterCard, or MIR credit cards.
Money transfers to Visa and MasterCard cards issued by foreign banks are suspended due to restrictions from the payment system.
Request → POST
Payment request for domestic card
curl -X POST \
"https://edge.qiwi.com/sinap/api/v2/terms/1963/payments" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"21131343",
"sum":{
"amount":1000,
"currency":"643"
},
"paymentMethod":{
"type":"Account",
"accountId":"643"
},
"fields": {
"account":"4256********1231"
}
}'
Payment request for foreign card
curl -X POST \
"https://edge.qiwi.com/sinap/api/v2/terms/1960/payments" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"21131343",
"sum":{
"amount":1000,
"currency":"643"
},
"paymentMethod":{
"type":"Account",
"accountId":"643"
},
"fields": {
"account": "402865XXXXXXXXXX",
"rec_address": "Ленинский проспект 131, 56",
"rec_city": "Москва",
"rec_country": "Россия",
"reg_name": "Виктор",
"reg_name_f": "Петров",
"rem_name": "Сергей",
"rem_name_f": "Иванов"
}
}'
POST /sinap/api/v2/terms/1963/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account":"4256XXXXXXXX1231"
}
}
POST /sinap/api/v2/terms/1960/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account": "402865XXXXXXXXXX",
"rec_address": "Ленинский проспект 131, 56",
"rec_city": "Москва",
"rec_country": "Россия",
"reg_name": "Виктор",
"reg_name_f": "Петров",
"rem_name": "Сергей",
"rem_name_f": "Иванов"
}
}
import requests
import time
# Card money transfer
def send_card(api_access_token, payment_data):
# payment_data - dictionary with all payment data
s = requests.Session()
s.headers['Accept'] = 'application/json'
s.headers['Content-Type'] = 'application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
postjson = {"id":"","sum": {"amount":"","currency":"643"},"paymentMethod": {"type":"Account","accountId":"643"},"fields": {"account":""}}
postjson['id'] = str(int(time.time() * 1000))
postjson['sum']['amount'] = payment_data.get('sum')
postjson['fields']['account'] = payment_data.get('to_card')
prv_id = payment_data.get('prv_id')
if payment_data.get('prv_id') in ['1960', '21012']:
postjson['fields']['rem_name'] = payment_data.get('rem_name')
postjson['fields']['rem_name_f'] = payment_data.get('rem_name_f')
postjson['fields']['reg_name'] = payment_data.get('reg_name')
postjson['fields']['reg_name_f'] = payment_data.get('reg_name_f')
postjson['fields']['rec_city'] = payment_data.get('rec_address')
postjson['fields']['rec_address'] = payment_data.get('rec_address')
res = s.post('https://edge.qiwi.com/sinap/api/v2/terms/' + prv_id + '/payments', json = postjson)
return res.json()
URL /sinap/api/v2/terms/ID/payments
Where:
ID — QIWI provider identifier. Possible values:
- 1963 — Visa money transfer to cards issued by Russian banks only.
- 21013 — MasterCard money transfer to cards issued by Russian banks only.
- 1960 — Visa money transfer to credit cards issued by banks in Albania, Andorra, Argentina, Armenia, Australia, Austria, Azerbaijan, Belarus, Belgium, Benin, Bosnia and Herzegovina, Brazil, Bulgaria, China, Croatia, Cyprus, Czech Republic, Denmark, Egypt, Estonia, Finland, France, Georgia, Germany , Greece, Hong Kong (China), Hungary, Iceland, India, Indonesia, Israel, Italy, Japan, Kazakhstan, Kenya, Korea Republic, Kuwait, Kyrgyzstan, Latvia, Lithuania, Luxembourg, Macao, China, Macedonia, Madagascar, Malaysia, Maldives , Malta, Republic of Moldova, Monaco, Mongolia, Montenegro, Namibia, Netherlands, New Zealand, Nigeria, Norway, Oman, Paraguay, Poland, Portugal, Qatar, Romania, Saudi Arabia, Republic of Serbia, Singapore, Slovakia, Slovenia, South Africa, Spain, Sri Lanka, Sweden, Tajikistan, Tanzania, Thailand, Turkey, Turkmenistan, United Arab Emirates, United Kingdom, Uzbekistan, Vietnam, Zambia.
- 21012 — MasterCard money transfer to credit cards issued by banks in Albania, Argentina, Armenia, Australia, Austria, Azerbaijan, Bangladesh, Barbados, Belarus, Belgium, Benin, Bosnia and Herzegovina, Burkina Faso, Brazil, Bulgaria, Cambodia, Cameroon United Republic, Chile, China, Colombia, Congo, Costa Rica, Croatia, Cyprus, Czech Republic, Democratic Republic of the Congo, Denmark, Dominican Republic, Ecuador, El Salvador, Egypt, Estonia, Finland, France, Georgia, Germany, Ghana, Greece, Guatemala, Hong Kong, Hungary, India, Indonesia, Ireland, Israel, Italy, Japan, Jordan, Kazakhstan, Kenya, Korea, Kuwait, Kyrgyzstan, Latvia, Lebanon, Lithuania, Luxembourg, Macao, Macedonia, Madagascar, Malaysia, Maldives, Malta, Mexico, Moldova, Monaco, Mongolia, Montenegro, Morocco, Namibia, Nigeria, Nepal, Netherlands, New Zealand, Nigeria, Norway, Oman, Panama, Paraguay, Peru, Philippines, Poland, Portugal, Romania, Qatar, Russian Federation, Saudi Arabia, Senegal, Serbia Republic, Singapore, Slovakia, Slovenia, South Africa, Spain, W ri-Lanka, Sweden, Switzerland, Tajikistan, Tanzania, Thailand, Tunisia, Turkey, Turkmenistan, United Arab Emirates, United Kingdom, Uzbekistan, Vietnam, Zambia.
- 31652 — Transfer to MIR national payment system cards.
- 22351 — Transfer to QIWI Virtual Card.
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON-object Payment in the request' body. Payment requisites in fields
object depend on the provider ID.
For ID 1963, 21013, 31652, 22351
Name | Type | Description |
---|---|---|
fields.account | String | Recipient's card number (no spaces) |
For ID 1960, 21012
Name | Type | Description |
---|---|---|
fields.account | String | Recipient's card number (no spaces) |
fields.rem_name | String | Sender's first name |
fields.rem_name_f | String | Sender's last name. Required for ID 1960 , 21012 only |
fields.rec_address | String | Sender's address (no zip code, only text) |
fields.rec_city | String | Sender's city |
fields.rec_country | String | Sender's country |
fields.reg_name | String | Recipient's first name |
fields.reg_name_f | String | Recipient's last name |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "21131343",
"terms": "1963",
"fields": {
"account": "4256********1231"
},
"sum": {
"amount": 1000,
"currency": "643"
},
"source": "account_643",
"transaction": {
"id": "4969142201",
"state": {
"code": "Accepted"
}
}
}
payment_data = {'prv_id': '1963', 'to_card' : '41548XXXXXXXX008', 'sum': 100}
jss = send_card(token, payment_data)
Successful response contains JSON-object PaymentInfo with accepted payment data.
Bank money transfer
Makes money transfer to personal bank cards/accounts opened in Russian banks.
Transfer to card number
Makes money transfer to cards issued by Russian banks.
Request → POST
curl -X POST \
"https://edge.qiwi.com/sinap/api/v2/terms/464/payments" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account_type": "1",
"account":"4256********1231",
"exp_date": "0623"
}
}'
POST /sinap/api/v2/terms/464/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account":"4256********1231",
"account_type": "1",
"exp_date": "0623"
}
}
URL /sinap/api/v2/terms/ID/payments
- ID - QIWI provider identifier. Possible values:
- 464 - Alfa Bank
- 804 - OTP Bank
- 810 - Rosselkhozbank
- 815 - Russkiy Standart
- 816 - VTB
- 821 - Promsvyazbank
- 870 - Sberbank
- 881 - Renaissance Credit
- 1134 - Moskovskiy Creditnyi Bank
- ID - QIWI provider identifier. Possible values:
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON object Payment in the request's body. Payment requisites in fields
object:
Name | Type | Description |
---|---|---|
fields.account | String | Recipient's card number (no spaces) |
fields.exp_date | String | Card expiry date, as MMYY (for example, 0218 ). Parameter is required for ID 464 and 821. |
fields.account_type | String | Bank identifier type. For each bank specific value applies: ID 464 - 1 ID 084 - 1 ID 815 - 1 ID 810 - 5 ID 816 - 5 ID 821 - 7 ID 870 - 5 ID 1134 - 5 ID 881 - 1 . |
fields.mfo | String | Bank MFO (BIK) |
fields.lname | String | Recipient's last name |
fields.fname | String | Recipient's first name |
fields.mname | String | Recipient's middle name |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "21131343",
"terms": "464",
"fields": {
"account": "4256********1231",
"account_type": "1",
"exp_date": "0423"
},
"sum": {
"amount": 1000,
"currency": "643"
},
"source": "account_643",
"transaction": {
"id": "4969142201",
"state": {
"code": "Accepted"
}
}
}
Successful response contains JSON-object PaymentInfo with accepted payment data.
Transfer to bank account
Makes money transfer to personal accounts opened in Russian banks. You can use quick transfer service (within an hour if transaction is made from 9:00 until 19:30).
Request → POST
curl -X POST \
"https://edge.qiwi.com/sinap/api/v2/terms/816/payments" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account_type": "2",
"urgent": "0",
"lname": "Иванов",
"fname": "Иван",
"mname": "Иванович",
"mfo": "046577795",
"account":"40817***"
}
}'
POST /sinap/api/v2/terms/816/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account_type": "2",
"urgent": "0",
"lname": "Иванов",
"fname": "Иван",
"mname": "Иванович",
"mfo": "046577795",
"account":"40817***"
}
}
URL /sinap/api/v2/terms/ID/payments
- ID - QIWI provider identifier. Possible values:
- 313 - HomeCredit Bank
- 464 - Alfa Bank
- 821 - Promsvyazbank
- 804 - OTP Bank
- 810 - Rosselkhozbank
- 816 - VTB
- 819 - Unicredit Bank
- 868 - QIWI Bank
- 870 - Sberbank
- 815 - Russkiy Standart
- 881 - Renaissance Credit
- 1134 - Moskovskiy Creditnyi Bank
- 27324 - Raiffeisen Bank
- ID - QIWI provider identifier. Possible values:
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON object Payment in the request's body. Payment requisites in fields
object:
Name | Type | Description |
---|---|---|
fields.account | String | Recipient's bank account number |
fields.urgent | String | Quick transfer flag. For 0 - not used; for 1 - make quick transfer by Urgent transfer service of Central Bank of Russia. Extra commission is paid for quick transfer |
fields.mfo | String | Bank MFO (BIK) |
fields.account_type | String | Bank identifier type. For each bank specific value applies: ID 464 - 2 ID 804 - 2 ID 810 - 2 ID 815 - 2 ID 816 - 2 ID 821 - 9 ID 819 - 2 ID 868 - 2 ID 870 - 2 ID 1134 - 2 ID 27324 - 2 ID 810 - 2 ID 816 - 5 ID 821 - 9 ID 881 - 2 ID 313 - 6 . |
fields.lname | String | Recipient's last name |
fields.fname | String | Recipient's first name |
fields.mname | String | Recipient's middle name |
fileds.agrnum | String | Bank agreement number - for ID 313 |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "21131343",
"terms": "464",
"fields": {
"account": "407121010910909011",
"account_type": "2"
},
"sum": {
"amount": 1000,
"currency": "643"
},
"source": "account_643",
"transaction": {
"id": "4969142201",
"state": {
"code": "Accepted"
}
}
}
Successful response contains JSON-object PaymentInfo with accepted payment data.
Other services
You can pay for services by user identifier. This request applies for QIWI providers with one user identifier and without requirement of account number online check.
Request → POST
curl -X POST \
"https://edge.qiwi.com/sinap/api/v2/terms/674/payments" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
-d '{
"id":"21131343",
"sum": {
"amount":100,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account":"111000000"
}
}'
POST /sinap/api/v2/terms/674/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
{
"id":"21131343",
"sum": {
"amount":100,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"account":"111000"
}
}
import requests
import time
# payment for service provider
def pay_simple_prv(api_access_token, prv_id, to_account, sum_pay):
s = requests.Session()
s.headers['Accept'] = 'application/json'
s.headers['Content-Type'] = 'application/json'
s.headers['authorization'] = 'Bearer ' + api_access_token
postjson = {"id":"","sum": {"amount":"","currency":"643"},"paymentMethod": {"type":"Account","accountId":"643"},"fields": {"account":""}}
postjson['id'] = str(int(time.time() * 1000))
postjson['sum']['amount'] = sum_pay
postjson['fields']['account'] = to_account
res = s.post('https://edge.qiwi.com/sinap/api/v2/terms/'+prv_id+'/payments', json = postjson)
return res.json()
URL /sinap/api/v2/terms/ID/payments
- ID - QIWI provider identifier. Possible values:
- 674 - OnLime
- Other Internet providers
- 1239 - Podari zhizn Charitable Foundation
- Other charitable foundations identifiers
- Find a service provider identifier
- ID - QIWI provider identifier. Possible values:
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON object Payment in the request's body. Payment requisites in fields
object:
Name | Type | Description |
---|---|---|
fields.account | String | User identifier |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "21131343",
"terms": "674",
"fields": {
"account": "111000"
},
"sum": {
"amount": 100,
"currency": "643"
},
"source": "account_643",
"transaction": {
"id": "4969142201",
"state": {
"code": "Accepted"
}
}
}
Successful response contains JSON-object PaymentInfo with accepted payment data.
Payment by any requisites
Makes payments for commercial services by their bank details.
Request → POST
curl -X POST \
"https://edge.qiwi.com/sinap/api/v2/terms/1717/payments" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>" \
--header "User-Agent: ***" \
-d '{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"extra_to_bik":"044525201",
"requestProtocol":"qw1",
"city":"МОСКВА",
"name":"ПАО АКБ \"АВАНГАРД\"",
"to_bik":"044525201",
"urgent":"0",
"to_kpp":"772111001",
"is_commercial":"1",
"nds":"НДС не облагается",
"goal":" Оплата товара по заказу №090738231",
"from_name_p":"Николаевич",
"from_name":"Иван",
"from_name_f":"Михайлов",
"info":"Коммерческие организации",
"to_name":"ООО \"Технический Центр ДЕЛЬТА\"",
"to_inn":"7726111111",
"account":"40711100000012321",
"toServiceId":"1717"
}
}'
POST /sinap/api/v2/terms/1717/payments HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
User-Agent: ****
{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"extra_to_bik":"044525201",
"requestProtocol":"qw1",
"city":"МОСКВА",
"name":"ПАО АКБ \"АВАНГАРД\"",
"to_bik":"044525201",
"urgent":"0",
"to_kpp":"772111001",
"is_commercial":"1",
"nds":"НДС не облагается",
"goal":" Оплата товара по заказу №090738231",
"from_name_p":"Николаевич",
"from_name":"Иван",
"from_name_f":"Михайлов",
"info":"Коммерческие организации",
"to_name":"ООО \"Технический Центр ДЕЛЬТА\"",
"to_inn":"7726111111",
"account":"40711100000012321",
"toServiceId":"1717"
}
}
URL /sinap/api/v2/terms/1717/payments
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send JSON object Payment in the request's body. Payment requisites in fields
object:
Name | Type | Description |
---|---|---|
fields.name | String | Recipient's bank name (escape quotes with \ ) |
fields.extra_to_bik | String | Recipient's bank MFO (BIK) |
fields.to_bik | String | Recipient's bank MFO (BIK) |
fields.city | String | Recipient's city of placement |
fields.info | String | Constant, Коммерческие организации (in Russian) |
fields.is_commercial | String | Service info, constant 1 |
fields.to_name | String | Recipient's organization name (escape quotes with \ ) |
fields.to_inn | String | Organization's TIN |
fields.to_kpp | String | Organization's KPP (code for the reason in the tax service regisration) |
fields.nds | String | Value-added tax flag. If you pay for invoice and there is no VAT, then put the string НДС не облагается (in Russian). Otherwise, put the string В т.ч. НДС (in Russian). |
fields.goal | String | Payment appointment |
fields.urgent | String | Urgent payment (0 - no, 1 - yes). Urgent payment is made in 10 minutes or more. It is applicable for weekdays from 9:00 to 20:30, Moscow time zone. Extra fee for the service is 25 rubles. |
fields.account | String | Recipient's account number |
fields.from_name | String | Recipient's first name |
fields.from_name_p | String | Recipient's middle name |
fields.from_name_f | String | Recipient's last name |
fields.requestProtocol | String | Service info, constant qw1 |
fields.toServiceId | String | Service info, QIWI provider ID 1717 |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "21131343",
"terms": "1717",
"fields": {
"extra_to_bik":"044525201",
"requestProtocol":"qw1",
"city":"МОСКВА",
"name":"ПАО АКБ \"АВАНГАРД\"",
"to_bik":"044525201",
"urgent":"0",
"to_kpp":"772111001",
"is_commercial":"1",
"nds":"НДС не облагается",
"goal":" Оплата товара по заказу №090738231",
"from_name_p":"Николаевич",
"from_name":"Иван",
"from_name_f":"Михайлов",
"info":"Коммерческие организации",
"to_name":"ООО \"Технический Центр ДЕЛЬТА\"",
"to_inn":"7726111111",
"account":"40711100000012321",
"toServiceId":"1717"
},
"sum": {
"amount": 1000,
"currency": "643"
},
"source": "account_643",
"transaction": {
"id": "10969142201",
"state": {
"code": "Accepted"
}
}
}
Successful response contains JSON-object PaymentInfo with accepted payment data.
QIWI provider search
Performs search of QIWI provider's ID for payment methods by keywords (for example, provider's name).
Request → GET
curl -X GET \
"https://edge.qiwi.com/search/v1/search?query=%D0%91%D0%B8%D0%BB%D0%B0%D0%B9%D0%BD+%D0%B4%D0%BE%D0%BC%D0%B0%D1%88%D0%BD%D0%B8%D0%B9+%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82" \
--header "Accept: application/json" \
--header "Authorization: Bearer <API token>"
GET /search/v1/search?query=%D0%91%D0%B8%D0%BB%D0%B0%D0%B9%D0%BD+%D0%B4%D0%BE%D0%BC%D0%B0%D1%88%D0%BD%D0%B8%D0%B9+%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82 HTTP/1.1
Accept: application/json
Authorization: Bearer <API token>
Host: edge.qiwi.com
import requests
# provider id by its name
def qiwi_com_search(search_phrase):
s = requests.Session()
search = s.get('https://edge.qiwi.com/search/v1/search', params={'query':search_phrase})
return search.json()['data']['items']
URL https://edge.qiwi.com/search/v1/search?query={value}
- query — keywords for provider's searching separated by spaces.
HEADERS
- Accept: application/json
- Authorization: Bearer QIWI Wallet API token
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"items": [
{
"name": "МТС Домашний интернет, ТВ и Телефония РФ",
"description": "МТС Домашний интернет, ТВ и Телефония РФ",
"uri": null,
"data": {
"id": 23729,
"logoUrl": "https://static.qiwi.com/img/providers/logoBig/23729_l.png",
"siteUrl": "http://www.mts.ru/internet/mts_stream/",
"category": {
"name": "Интернет, ТВ, IP-телефония"
},
"type": "PROVIDER"
}
},
...
]
}
# Provider search: response parsing
prv = qiwi_com_search('Билайн домашний интернет')[0]['data']['id']
print(str(prv))
Successful JSON-response contains IDs of the found QIWI providers:
Response field | Type | Description |
---|---|---|
items | Array of objects | List of providers |
items[].data.id | Number | Provider's ID in the array's element |
API data models
Payment class
{
"id":"21131343",
"sum": {
"amount":1000,
"currency":"643"
},
"paymentMethod": {
"type":"Account",
"accountId":"643"
},
"fields": {
"extra_to_bik":"044525201",
"requestProtocol":"qw1",
"city":"МОСКВА",
"name":"ПАО АКБ \"АВАНГАРД\"",
"to_bik":"044525201",
"urgent":"0",
"to_kpp":"772111001",
"is_commercial":"1",
"nds":"НДС не облагается",
"goal":" Оплата товара по заказу №090738231",
"from_name_p":"Николаевич",
"from_name":"Иван",
"from_name_f":"Михайлов",
"info":"Коммерческие организации",
"to_name":"ООО \"Технический Центр ДЕЛЬТА\"",
"to_inn":"7726111111",
"account":"40711100000012321",
"toServiceId":"1717"
}
}
Object describes payment data for QIWI Wallet provider.
Name | Type | Description | |
---|---|---|---|
id | String | Required. Client transaction ID (max 20 digits). Must be unique for each transaction. Increment with each following transaction. To satisfy these requirements, set it to 1000*(Standard Unix time in seconds). | + |
sum | Object | Required. Payment amount data | |
sum.amount | Number | Payment amount value (rubles and kopeks, separator . ). Positive number rounded down to 2 decimals. If you specify more decimals, our system will round the number down to the same precision. |
|
sum.currency | String | Payment currency (only rubles, 643 ) |
|
paymentMethod | Object | Required. QIWI wallet account to fund the payment | |
paymentMethod.type | String | Constant, Account |
|
paymentMethod.accountId | String | Constant, 643 |
|
fields | Object | Required. Payment requisites. Object fields depend on provider ID. | |
comment | String | Payment comment. Used for QIWI wallet transfer or conversion only |
PaymentInfo class
{
"id": "150217833198900",
"terms": "99",
"fields": {
"account": "79121238345"
},
"sum": {
"amount": 100,
"currency": "643"
},
"transaction": {
"id": "11155897070",
"state": {
"code": "Accepted"
}
},
"source": "account_643",
"comment": "My comment"
}
Object describes QIWI wallet transaction data and returns in response from Payment API.
Name | Type | Description |
---|---|---|
id | Number | id parameter from the original request |
terms | String | QIWI provider ID used for the payment |
fields | Object | fields object from the original request. Card number returns in masked form |
sum | Object | sum object from the original request |
source | String | Always constant, account_643 |
comment | String | comment parameter from the original request (if exists in the request) |
transaction | Object | Object with QIWI transaction data |
transaction.id | String | QIWI transaction ID |
transaction.state | Object | Current state of the transaction |
state.code | String | Current status of the transaction. Only Accepted is returned (it means that the payment is accepted for processing). Actual transaction status can be obtained from Payments history API. |
Invoices
Invoice is the universal request for payment or money transfer from user's QIWI wallet.
API provides operations of invoice creation (only P2P invoices for money transfer to another QIWI wallet), payment, rejection, and also method for requesting list of unpaid invoices issued to your QIWI wallet.
Invoice creation and P2P token
You can issue invoices to any QIWI wallet by using P2P invoices API. Use special P2P token for authorization in P2P invoices API.
How to get P2P token
P2P token issue has been stopped. Sorry for the inconvenience.
Authorize on p2p.qiwi.com, or use the given request. You may also specify Invoice payment callbacks URL in this request.
The method returns P2P tokens in JSON format:
PublicKey
response field — token for using with Payment form;SecretKey
response field — token for this P2P API.
Use QIWI Wallet API token for authorization.
Request → POST
curl -X POST \
https://edge.qiwi.com/widgets-api/api/p2p/protected/keys/create \
-H 'Authorization: Bearer <API token>' \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-d '{"keysPairName":"Name","serverNotificationsUrl":"https://test.com"}'
POST /widgets-api/api/p2p/protected/keys/create HTTP/1.1
Host: edge.qiwi.com
Authorization: Bearer 3b7beb2044c4dd4a8f4588d4a6b6c93f
Content-Type: application/json
User-Agent: ****
{"keysPairName":"Name", "serverNotificationsUrl":"https://test.com"}
URL /widgets-api/api/p2p/protected/keys/create
HEADERS
- Content-Type: application/json
- Authorization: Bearer QIWI Wallet API token
Parameters
Send parameters in JSON-body:
Name | Type | Description |
---|---|---|
keysPairName | String | Name for the couple of P2P tokens |
serverNotificationsUrl | String | Invoice payment callbacks URL (optional) |
List of invoices
Returns only unpaid invoices issued to your wallet. Invoices are placed in the list in reverse chronological order.
By default, the list is paginated on 50 elements on each page. You can specify the number of elements on each page. You may use filters: invoice creation period of dates and starting invoice ID.
Request → GET
curl -X GET \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <a href="#auth_data">QIWI Wallet API token</a>' \
'https://edge.qiwi.com/checkout-api/api/bill/search?statuses=READY_FOR_PAY&rows=50'
GET /checkout-api/api/bill/search?statuses=READY_FOR_PAY&rows=50 HTTP/1.1
Accept: application/json
Authorization: Bearer <a href="#auth_data">QIWI Wallet API token</a>
Host: edge.qiwi.com
User-Agent: ****
URL /checkout-api/api/bill/search?statuses=READY_FOR_PAY¶meter=value
HEADERS
- Accept: application/json
- Authorization: Bearer SecretKey
Parameters
Send parameters in the request query URL:
Name | Type | Description |
---|---|---|
statuses | String | Unpaid invoice status. Only READY_FOR_PAY . Required parameter. |
rows | Integer | Maximum number of invoices to be returned, for list pagination. Integer number from 1 to 50. Default value is 50. |
min_creation_datetime | Long | Lower time limit for invoice search, Unix-time |
max_creation_datetime | Long | Greater time limit for invoice search, Unix-time |
next_id | Number | Starting invoice identifier for invoice search. Only invoices with IDs equal or smaller than this ID are returned. Use it for obtaining next invoices in the paginated list. |
next_creation_datetime | Long | Starting date for invoice search, Unix-time. Only invoices created before this date are returned. Use it for obtaining next invoices in the paginated list. |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"bills": [
{
"id": 1063702405,
"external_id": "154140605",
"creation_datetime": 1523025585000,
"expiration_datetime": 1523026003808,
"sum": {
"currency": 643,
"amount": 100
},
"status": "READY_FOR_PAY",
"type": "MERCHANT",
"repetitive": false,
"provider": {
"id": 480706,
"short_name": "Интернет-магазин цветов",
"long_name": "ООО «Цветы»",
"logo_url":"https://static.qiwi.com/img/providers/logoBig/480706_l.png"
},
"comment": "Пополнение счета 13515573",
"pay_url":"https://oplata.qiwi.com/form?shop=480706&transaction=102263702405"
}
]
}
Successful JSON response includes a list of unpaid invoices according to the conditions of the request:
Response field | Type | Description |
---|---|---|
bills | Array[Object] | List of invoices. List length is rows parameter from the original request, or 50, if it is absent |
bills[].id | Integer | QIWI Wallet invoice ID |
bills[].external_id | String | Merchant's invoice ID |
bills[].creation_datetime | Long | Date/time of the invoice creation, Unix-time |
bills[].expiration_datetime | Long | Date/time of the invoice expiration, Unix-time |
bills[].sum | Object | Invoice amount data |
sum.currency | Integer | Invoice currency |
sum.amount | Number | Invoice amount |
bills[].status | String | Constant, READY_FOR_PAY |
bills[].type | String | Constant, MERCHANT |
bills[].repetitive | Boolean | Service data |
bills[].provider | Object | Merchant information |
provider.id | Integer | QIWI identifier |
provider.short_name | String | Short name |
provider.long_name | String | Full name |
provider.logo_url | String | Logo URL |
bills[].comment | String | Invoice comment |
bills[].pay_url | String | URL to pay for the invoice on QIWI Payment Form |
Invoice payment
Makes invoice payment immediately without SMS confirmation.
Request → POST
curl -X POST \
'https://edge.qiwi.com/checkout-api/invoice/pay/wallet' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <a href="#auth_data">QIWI Wallet API token</a>' \
-d '{
"invoice_uid": "1063702405",
"currency": "643"
}'
POST /checkout-api/invoice/pay/wallet HTTP/1.1
Accept: application/json
Content-type: application/json
Authorization: Bearer <a href="#auth_data">QIWI Wallet API token</a>
Host: edge.qiwi.com
User-Agent: ****
{
"invoice_uid": "1063702405",
"currency": "643"
}
URL /checkout-api/invoice/pay/wallet
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer SecretKey
Parameters
Required parameters in JSON body:
Name | Type | Description |
---|---|---|
invoice_uid | String | QIWI invoice ID, taken from bills[].id field of invoice data |
currency | String | Invoice currency, taken from bills[].sum.currency field of invoice data) |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"invoice_status": "PAID_STATUS",
"is_sms_confirm": false,
"WALLET_ACCEPT_PAY_RESULT": {}
}
Successful response contains JSON with paid invoice status:
Field | Type | Description |
---|---|---|
invoice_status | String | Invoice payment status, PAID_STATUS . Any other status means unsuccessful transaction. |
is_sms_confirm | String | SMS confirmation flag |
Cancelling unpaid invoice
Rejects an unpaid invoice, which makes the invoice unavailable for payment.
Request → POST
curl -X POST \
'https://edge.qiwi.com/checkout-api/api/bill/reject' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <a href="#auth_data">QIWI Wallet API token</a>' \
-d '{ "id": 1034353453 }'
POST /checkout-api/api/bill/reject HTTP/1.1
Accept: application/json
Authorization: Bearer <a href="#auth_data">QIWI Wallet API token</a>
Content-type: application/json
Host: edge.qiwi.com
User-Agent: ****
{
"id": 1034353453
}
URL /checkout-api/api/bill/reject
HEADERS
- Accept: application/json
- Content-type: application/json
- Authorization: Bearer SecretKey
Parameter
Required parameter in JSON body:
Name | Type | Description |
---|---|---|
id | Integer | Invoice ID to reject, taken from bills[].id field of invoice data |
Response ←
HTTP/1.1 200 OK
Successful response has HTTP code 200
.
Callbacks
Edit on GitHub
Webhook allows you to receive real-time HTTP notifications of events (outgoing / incoming payments). You need to implement a web service to receive and processing of POST-requests according to the requests format.
You need to respond the notification with HTTP 200 OK within 1-2 sec. If QIWI service has no response, it sends next notification in 10 min, then in 1 hour.
Pools of IP-addresses from which QIWI service sends notifications:
- 79.142.16.0/20
- 195.189.100.0/22
- 91.232.230.0/23
- 91.213.51.0/24
If your web service works behinds the firewall, you need to add these IP-addresses to the list of allowed addresses for incoming TCP packets.
Quick start
- Implement web service for webhook requests. Make sure to implement correctly the digital signature verification.
- Register your service. Please note that its URL original length (before URL-encoding) cannot be longer than 100 symbols.
- Request for signature key.
- Test your service with test request. Empty notification will be sent to your service registered at stage 2.
To change webhook service URL:
- Remove current webhook service.
- Register new webhook service. Please note that its URL original length (before URL-encoding) cannot be longer than 100 symbols.
- Request for new signature key.
- Test your service with test request. Empty notification will be sent to your service registered at stage 2.
Processing notification
Outgoing payments - notification of payment in process
POST /some-hook.php HTTP/1.1
Accept: application/json
Content-type: application/json
Host: example.com
{"hash": "50779a03d90c4fa60ac44dfd158dbceec0e9c57fa4cf4f5298450fdde1868945",
"hookId": "f57f95e2-149f-4278-b2cb-4114bc319727",
"messageId": "f9a197a8-26b6-4d42-aac4-d86b789c373c",
"payment": {"account": "myAccount",
"comment": "My comment",
"commission": Null,
"date": "2018-05-18T16:05:15+03:00",
"errorCode": "0",
"personId": 79254914194,
"provider": 25549,
"signFields": "sum.currency,sum.amount,type,account,txnId",
"status": "WAITING",
"sum": {"amount": 1.73, "currency": 643},
"total": {"amount": 1.73, "currency": 643},
"txnId": "13117338074",
"type": "OUT"},
"test": false,
"version": "1.0.0"}
Outgoing payment - notification of successful payment
POST /some-hook.php HTTP/1.1
Accept: application/json
Content-type: application/json
Host: example.com
{"hash": "50779a03d90c4fa60ac44dfd158dbceec0e9c57fa4cf4f5298450fdde1868945",
"hookId": "f57f95e2-149f-4278-b2cb-4114bc319727",
"messageId": "6e2a0e32-4c8d-4fe2-9eed-fe3b6a726ff4",
"payment": {"account": "thedandod",
"comment": "My comment",
"commission": {"amount": 0.0, "currency": 643},
"date": "2018-05-18T16:05:15+03:00",
"errorCode": "0",
"personId": 79254914194,
"provider": 25549,
"signFields": "sum.currency,sum.amount,type,account,txnId",
"status": "SUCCESS",
"sum": {"amount": 1.73, "currency": 643},
"total": {"amount": 1.73, "currency": 643},
"txnId": "13117338074",
"type": "OUT"},
"test": false,
"version": "1.0.0"}
Outgoing payments - notification of unsuccessful payment
POST /some-hook.php HTTP/1.1
Accept: application/json
Content-type: application/json
Host: example.com
{"hash": "0637b07b1018d76585db26b0f8077016b12996006429e22a7dc5b6982710a1ef",
"hookId": "f57f95e2-149f-4278-b2cb-4114bc319727",
"messageId": "1133873b-9bb6-4adb-9bfe-7be3a9aa999f",
"payment": {"account": "borya241203",
"comment": "",
"commission": None,
"date": "2018-05-20T05:19:16+03:00",
"errorCode": "5",
"personId": 79254914194,
"provider": 25549,
"signFields": "sum.currency,sum.amount,type,account,txnId",
"status": "ERROR",
"sum": {"amount": 1.01, "currency": 643},
"total": {"amount": 1.01, "currency": 643},
"txnId": "13126423989",
"type": "OUT"},
"test": false,
"version": "1.0.0"}
Incoming payment - notification of successful payment
POST /some-hook.php HTTP/1.1
Accept: application/json
Content-type: application/json
Host: example.com
{"hash": "a56ed0090fa3fd2fd0b002ed80f85a120037a6a85f840938888275e1631da96f",
"hookId": "8c79f60d-0272-476b-b120-6e7629467328",
"messageId": "bba24947-ab5f-4b33-881b-738fc3a4c9e1",
"payment": {"account": "79042426915",
"comment": "Replenishing wallet",
"commission": {"amount": 0.0, "currency": 643},
"date": "2018-03-25T13:16:48+03:00",
"errorCode": "0",
"personId": 79645265240,
"provider": 7,
"signFields": "sum.currency,sum.amount,type,account,txnId",
"status": "SUCCESS",
"sum": {"amount": 1.09, "currency": 643},
"total": {"amount": 1.09, "currency": 643},
"txnId": "12565018935",
"type": "IN"},
"test": false,
"version": "1.0.0"}
Each notification is an incoming POST-request with single payment data in JSON body. JSON scheme is as followed:
Field | Type | Description |
---|---|---|
hookId | String (UUID) | Unique webhook id |
messageId | String (UUID) | Unique notification id |
payment | Object | Payment data |
payment.txnId | String | QIWI Wallet transaction ID |
payment.account | String | For outgoing payments - recipients account number. For incoming payments - sender number, self-service kiosk number, or top-up agent name |
payment.signFields | String | A list of fields in payment object (separated by comma) to use for HmacSHA256 hash calculation of notification signature (see hash field) |
payment.personId | Integer | Your wallet number |
payment.date | String DateTime | Payment date/time, in Moscow time zone, as YYYY-MM-DD'T'hh:mm:ss+03:00 |
payment.errorCode | String | Payment error code |
payment.type | String | Payment type:IN - wallet top-up, OUT - payment |
payment.status | String | Payment status:WAITING - payment in process,SUCCESS - successful payment,ERROR - payment error. |
payment.provider | Integer | Provider ID in QIWI Wallet |
payment.comment | String | Transaction comment |
payment.sum | Object | Payment amount data |
sum.amount | Number(Decimal) | Amount |
sum.currency | Number(3) | Currency code |
payment.commission | Object | Payment commission |
commission.amount | Number(Decimal) | Commission amount |
commission.currency | Number(3) | Currency code |
payment.total | Object | Total payment amount |
total.amount | Number(Decimal) | Amount |
total.currency | Number(3) | Currency code |
test | Boolean | Flag indicating test notification |
version | String | Webhook API version |
hash | String | Hash of the notification's digital signature |
Notification signature verification
<?php
//Procedure returns string of sorted values from notification parameters and signature hash for verification
function getReqParams(){
//Make sure that it is a POST request.
if(strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0){
throw new Exception('Request method must be POST!');
}
//Receive the RAW post data.
$content = trim(file_get_contents("php://input"));
//Attempt to decode the incoming RAW post data from JSON.
$decoded = json_decode($content, true);
//If json_decode failed, the JSON is invalid.
if(!is_array($decoded)){
throw new Exception('Received content contained invalid JSON!');
}
//Check if test
if ($decoded['test'] == 'true') {
throw new Exception('Test!');
}
// String of parameters
$reqparams = $decoded['payment']['sum']['currency'] . '|' . $decoded['payment']['sum']['amount'] . '|'. $decoded['payment']['type'] . '|' . $decoded['payment']['account'] . '|' . $decoded['payment']['txnId'];
// Signature
foreach ($decoded as $name=>$value) {
if ($name == 'hash') {
$SIGN_REQ = $value;
}
}
return [$reqparams, $SIGN_REQ];
}
// Resulted data
$Request = getReqParams();
// Base64 encoded key for decryption (method /hook/{hookId}/key)
$NOTIFY_PWD = "JcyVhjHCvHQwufz+IHXolyqHgEc5MoayBfParl6Guoc=";
// Get SHA-256 hash of the string and encrypt with your webhook key
$reqres = hash_hmac("sha256", $Request[0], base64_decode($NOTIFY_PWD));
// Verify signature
if (hash_equals($reqres, $Request[1])) {
$error = array('response' => 'OK');
}
else $error = array('response' => 'error');
//Response
header('Content-Type: application/json');
$jsonres = json_encode($error);
echo $jsonres;
error_log('error code' . $jsonres);
?>
import base64
import hmac
import hashlib
# Base64 encoded key (get it with /hook/{hookId}/key request)
webhook_key_base64 = 'JcyVhjHCvHQwufz+IHXolyqHgEc5MoayBfParl6Guoc='
# notification parameters
data = '643|1|IN|+79161112233|13353941550'
webhook_key = base64.b64decode(bytes(webhook_key_base64,'utf-8'))
print(hmac.new(webhook_key, data.encode('utf-8'), hashlib.sha256).hexdigest())
To verify signature of a notification, proceed with the following:
- Take values of fields specified in
payment.signFields
field of the notification JSON (in the same order) as Strings. - Join them with
|
separator. - Encode the resulted string with SHA-256 and signature key.
- Compare obtained value with
hash
field of the notification.
Example of signature verification (see also PHP procedure on the right tab):
- You get signature key, encoded in Base64:
JcyVhjHCvHQwufz+IHXolyqHgEc5MoayBfParl6Guoc=
- You get notification:
{"messageId":"7814c49d-2d29-4b14-b2dc-36b377c76156","hookId":"5e2027d1-f5f3-4ad1-b409-058b8b8a8c22","payment":{"txnId":"13353941550","date":"2018-06-27T13:39:00+03:00","type":"IN","status":"SUCCESS","errorCode":"0","personId":78000008000,"account":"+79161112233","comment":"","provider":7,"sum":{"amount":1,"currency":643},"commission":{"amount":0,"currency":643},"total":{"amount":1,"currency":643},"signFields":"sum.currency,sum.amount,type,account,txnId"},"hash":"76687ffe5c516c793faa46fafba0994e7ca7a6d735966e0e0c0b65eaa43bdca0","version":"1.0.0","test":false}
- Join values of the fields specified in
signFields
field (sum.currency,sum.amount,type,account,txnId
):
643|1|IN|+79161112233|13353941550
- The obtained string is encoded with SHA-256 and the Base64-decoded key from step 1:
f05c4e7bdf00620205d47696d77f924bfd3ba4d02b0398ac8a626e737dc27243
Result coincides withhash
field from the notification. The verification is successful.
Webhook service registration
Request → PUT
curl -X PUT \
"https://edge.qiwi.com/payment-notifier/v1/hooks?hookType=1¶m=http%3A%2F%2Fexample.com%2Fcallbacks%2F&txnType=2" \
-H "accept: */*" \
-H "authorization: Bearer <API token>"
PUT /payment-notifier/v1/hooks?hookType=1¶m=http%3A%2F%2Fexample.com%2Fcallbacks%2F&txnType=2 HTTP/1.1
Host: edge.qiwi.com
Authorization: Bearer <API token>
User-Agent: ****
URL /payment-notifier/v1/hooks?parameter=value
HEADERS
- Authorization: Bearer QIWI Wallet API token
- Accept: application/json
Parameters
Send parameters in the request query. All parameters are required.
Name | Type | Description |
---|---|---|
hookType | Integer | Webhook type. Only 1 . |
param | URL-encoded | Service URL. URL original length (before URL-encoding) must be within 100 symbols. URL must be accessible from the Internet. |
txnType | String | Choose type of transactions for notifications: 0 - only incoming transactions (wallet top-up); 1 - only outgoing transactions (payments); 2 - all transactions |
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"hookId":"d63a8729-f5c8-486f-907d-9fb8758afcfc",
"hookParameters":{
"url":"http://example.com/callbacks/"
},
"hookType":"WEB",
"txnType":"BOTH"
}
Response in JSON.
Field | Type | Description |
---|---|---|
hookId | String | Webhook service UUID |
hookParameters | Object | Webhook service parameters |
hookParameters.url | String | Webhook service URL |
hookType | String | Webhook type (only WEB ) |
txnType | String | Transactions type for notifications (IN - incoming, OUT - outgoing, BOTH - all) |
Remove webhook service registration
Request → DELETE
curl -X DELETE \
"https://edge.qiwi.com/payment-notifier/v1/hooks/<hook-id>" \
-H "accept: */*" \
-H "authorization: Bearer <API token>"
DELETE /payment-notifier/v1/hooks/d63a8729-f5c8-486f-907d-9fb8758afcfc HTTP/1.1
Host: edge.qiwi.com
Authorization: Bearer <API token>
User-Agent: ****
URL /payment-notifier/v1/hooks/hookId
- hookId - webhook UUID
HEADERS
- Authorization: Bearer QIWI Wallet API token
- Accept: application/json
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"response":"Hook deleted"
}
Response in JSON.
Field | Type | Description |
---|---|---|
response | String | Operation result |
Secret key provision
Each notification contains digital signature encoded by secret key. Use this request to get the key.
Request → GET
curl -X GET \
"https://edge.qiwi.com/payment-notifier/v1/hooks/<hook-id>/key" \
-H "accept: */*" \
-H "accept: */*" \
-H "authorization: Bearer <API token>"
GET /payment-notifier/v1/hooks/d63a8729-f5c8-486f-907d-9fb8758afcfc/key HTTP/1.1
Host: edge.qiwi.com
Authorization: Bearer <API token>
User-Agent: ****
URL /payment-notifier/v1/hooks/hookId/key
- hookId — webhook UUID
HEADERS
- Authorization: Bearer QIWI Wallet API token
- Accept: application/json
Response ←
HTTP/1.1 201 Created
Content-Type: application/json
{
"key":"L8UVF3JkLVUr6r70LiE0A9/5WoGGwWKG2pI/e+l/9fs="
}
Response in JSON.
Field | Type | Description |
---|---|---|
key | String | Base64-encoded key |
Secret key change
Changes the secret key for notifications signature.
Request → POST
curl -X POST \
"https://edge.qiwi.com/payment-notifier/v1/hooks/<hook-id>/newkey" \
-H "accept: */*" \
-H "authorization: Bearer <API token>"
POST /payment-notifier/v1/hooks/d63a8729-f5c8-486f-907d-9fb8758afcfc/newkey HTTP/1.1
Host: edge.qiwi.com
Authorization: Bearer <API token>
User-Agent: ****
URL /payment-notifier/v1/hooks/hookId/newkey
- hookId - webhook UUID
HEADERS
- Authorization: Bearer QIWI Wallet API token
- Accept: application/json
Response ←
HTTP/1.1 201 Created
Content-Type: application/json
{
"key":"OikS4/CcIbSf+yYGnLbnOige8RGoYmGxs/LNMwkJy7Q="
}
Response in JSON.
Field | Type | Description |
---|---|---|
key | String | Base64-encoded new key |
Webhook service data
Gets the active webhook service linked to your wallet.
Request → GET
curl -X GET \
"https://edge.qiwi.com/payment-notifier/v1/hooks/active" \
-H "accept: */*" \
-H "accept: */*" \
-H "authorization: Bearer <API token>"
GET /payment-notifier/v1/hooks/active HTTP/1.1
Host: edge.qiwi.com
Authorization: Bearer <API token>
User-Agent: ****
URL /payment-notifier/v1/hooks/active
HEADERS
- Authorization: Bearer QIWI Wallet API token
- Accept: application/json
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"hookId":"d63a8729-f5c8-486f-907d-9fb8758afcfc",
"hookParameters":{
"url":"http://example.com/callbacks/"
},
"hookType":"WEB",
"txnType":"BOTH"
}
Response in JSON.
Field | Type | Description |
---|---|---|
hookId | String | Active webhook UUID |
hookParameters | Object | Webhook service parameters |
hookParameters.url | String | Webhook URL |
hookType | String | Webhook type (only WEB ) |
txnType | String | Transactions type for notifications (IN - incoming (wallet topup), OUT - outgoing (payments), BOTH - all) |
Test webhook service
Use this request to test your webhook service. As a result of the request, empty test notification is sent to the URL of the active webhook service.
Request → GET
curl -X GET \
"https://edge.qiwi.com/payment-notifier/v1/hooks/test" \
-H "accept: */*" \
-H "authorization: Bearer <API token>"
GET /payment-notifier/v1/hooks/test HTTP/1.1
Host: edge.qiwi.com
Authorization: Bearer <API token>
User-Agent: ****
URL /payment-notifier/v1/hooks/test
HEADERS
- Authorization: Bearer QIWI Wallet API token
- Accept: application/json
Response ←
HTTP/1.1 200 OK
Content-Type: application/json
{
"response":"Webhook sent"
}
Response in JSON.
Field | Type | Description |
---|---|---|
response | String | Notification on the request |
Error Codes
API returns the following HTTP codes in case of errors.
HTTP code | API | Description |
---|---|---|
400 | All | Wrong data format of request |
401 | All | Wrong API token or token expired |
403 | All | Not enough rights of API token for the request |
404 | Payments history, Transaction info, Receipt | Transaction not found or no payments with such data |
404 | Balances, User's profile, Identification | Wallet not found |
404 | Callbacks | Active webhook not found |
404 | Pay/Cancel invoice | Invoice not found |
422 | Webhook registration | Wrong domain/subnet/host in new webhook URL, wrong webhook type or transactions type, or webhook already exists and is active |
423 | All | Too many requests, service temporary unavailable |
500 | All | Internal service error (webhook URL too long, infrastructure maintenance, resource is unavailable and so on) |
The following errors return in errorCode
field in responses to payments history and transaction info requests:
errorCode | Description |
---|---|
0 | OK |
3 | Technical error. Repeat the request later |
4 | Incorrect format of phone or account number. Check the data |
5 | No such number. Check the data and try again |
8 | Technical problem on the recipient's bank side. Try again later |
57 | Recipient's wallet status not allowing the money transfer. Ask them to enter passport data in QIWI Wallet to increase status level. |
131 | Payment type unavailable for your country |
166 | Your wallet status not allowing the money transfer. Enter passport data in QIWI Wallet to increase status level. |
167 | Recipient's wallet status not allowing the money transfer. Ask them to enter passport data in QIWI Wallet to increase status level. |
202 | Technical error. Repeat the payment later |
204 | Your wallet status not allowing the cash topup. Enter passport data in QIWI Wallet to increase status level. |
220 | Not enough funds. Replenish your wallet |
241 | Payment amount must be larger than 1 ruble |
242 | Payment amount larger than maximum allowed |
254 | Payment amount must be larger than 1 ruble |
271 | Technical issue on the recipient's bank side. Try again later |
300 | Technical error. Repeat the payment later |
303 | Wrong phone number - enter 10 digits |
319 | Your wallet status not allowing the money transfer. Enter passport data in QIWI Wallet to increase status level. |
407 | Not enough funds on your card |
408 | You already have the same payment - pay or cancel it |
455 | Payment is not possible due to limit on minimum balance |
461 | Time to confirm operation is expired. Try again later |
472 | Not enough funds on your wallet - replenish it |
500 | Technical error on the recipient's bank side. Contact the bank's Support service |
522 | Recipient's card wrong number or expiration date. Check data and try again |
547 | Recipient's card wrong expiration date. Check data and try again |
548 | Recipient's card expired |
558 | Payment amount larger than maximum allowed |
561 | Bank where the money is transferring does not accept the payment. Contact the bank's Support service |
700 | Limit for your wallet current status is exceeded. Increase your status level or check your current limit in Profile section |
702 | Payment is not possible due to recipient's limit. Its balance's limit is exceeded. Recipient has to contact with our Support |
704 | The monthly limit on your wallet has been exceeded. To remove the restrictions, increase your wallet status in Profile section |
705 | The monthly limit on your wallet has been exceeded. To remove the restrictions, increase your wallet status in Profile section |
710 | Transfer is not possible - the weekly limit of payments for the same recipient have been exceeded |
711 | Transfer is not possible. You have exceeded the monthly payment limit for such transactions |
716 | You have exceeded the monthly limit on withdrawals from the card. To remove the restrictions, increase your wallet status in Profile section |
717 | You have exceeded the daily limit on withdrawals from the card. To remove the restrictions, increase your wallet status in Profile section |
746 | Transfer is impossible - the limit for the same recipient has been exceeded |
747 | Transfer is not possible. The number of operations for the same recipient has been exceeded |
749 | Technical error. Contact our Support |
750 | Technical error. Repeat the payment later |
757 | The limit on the number of payments has been exceeded. To remove the restrictions, increase your wallet status in Profile section |
797 | Payment has been cancelled, the money is returned to your wallet |
852 | Transfer is impossible - the limit for the same recipient has been exceeded |
866 | Payment not processed. Limit on outgoing transfers has been exceeded - 5 000 RUB from RUB, USD, EUR accounts to KZT monthly. Increase your wallet status in Profile section and pay without limits |
867 | Payment not processed. Limit on incoming transfers has been exceeded - 5 000 RUB from RUB, USD, EUR accounts to KZT monthly. Increase your wallet status in Profile section and pay without limits |
893 | Transfer rejected. Date is expired |
901 | The code to confirm the payment has expired. Repeat the payment |
943 | The limit on transfers per month is exceeded. Increase your wallet status in Profile section and transfer without restrictions |
1050 | The limit on such operations is exceeded. Increase your wallet status in Profile section and expand your options |
7000 | Payment rejected. Check card's details and repeat the payment |
7600 | Payment rejected. Contact the bank that issued the card |