Android - In_App_Billing

vermontdroningMobile - Wireless

Dec 10, 2013 (3 years and 8 months ago)

98 views

 
 
ANDROID  MARKET
 
In
-­‐
app  Billing
 
 
 
 
 
 
 
 
 
 
 
 
 
By  Otilio
 
http://www.otilio.eu
 
R
ev.
 
0
 
In
-­‐
app  Billing
 
 
Topics
 
1.

Overview  of  In
-­‐
app  Billing
 
2.

Implementing  In
-­‐
app  Billing
 
3.

Security  and  Design
 
4.

Testing  In
-­‐
app  Billing
 
5.

Administering  In
-­‐
app  Billing
 

Reference
 
1.

In
-­‐
app  Billing  Reference
 

Android  Market  In
-­‐
app  Billing  is  an  Android  Market  service  that  lets  you  sell  digital  content  in  your  
applications.  You  can  use  the  service  to  
sell  a  wide  range  of  content,  including  downloadable  
content  such  as  media  files  or  photos,  and  virtual  content  such  as  game  levels  or  potions.
 
When  you  use  Android  Market

s  in
-­‐
app  billing  service  to  sell  an  item,  Android  Market  handles  all  
checkout  detail
s  so  your  application  never  has  to  directly  process  any  financial  transactions.  
Android  Market  uses  the  same  checkout  service  that  is  used  for  application  purchases,  so  your  
users  experience  a  consistent  and  familiar  purchase  flow  (see  figure  1).  Also,  the
 
transaction  fee  for  
in
-­‐
app  purchases  is  the  same  as  the  transaction  fee  for  application  purchases  (30%).
 
Any  application  that  you  publish  through  Android  Market  can  implement  in
-­‐
app  billing.  No  special  
account  or  registration  is  required  other  than  an  And
roid  Market  publisher  account  and  a  Google  
Checkout  Merchant  account.  Also,  because  the  service  uses  no  dedicated  framework  APIs,  you  can  
add  in
-­‐
app  billing  to  any  application  that  uses  a  minimum  API  level  of  4  or  higher.
 
To  help  you  integrate  in
-­‐
app  billi
ng  into  your  application,  the  Android  SDK  provides  a  sample  
application  that  demonstrates  a  simple  implementation  of  in
-­‐
app  billing.  The  sample  application  
contains  examples  of  billing
-­‐
related  classes  you  can  use  to  implement  in
-­‐
app  billing  in  your  
applica
tion.  It  also  contains  examples  of  the  database,  user  interface,  and  business  logic  you  might  
use  to  implement  in
-­‐
app  billing.
 
Important
:  Although  the  sample  application  is  a  working  example  of  how  you  can  implement  in
-­‐
app  
billing,  we  
strongly  recommend
 
th
at  you  modify  and  obfuscate  the  sample  code  before  you  use  it  in  
a  production  application.  For  more  information,  see  
Security  and  Design
.
 

Figure  1.
 
Applications  initiate  in
-­‐
app  billing  requests  through  their  own  UI  (first  screen).  Android  
Market  responds  to  the  request  by  providing  the  checkout  user  interface  (middle  screen).  When  
checkout  is  complete,  the  application  resumes.
 
To  learn  more  about  And
roid  Market

s  in
-­‐
app  billing  service  and  start  integrating  it  into  your  
applications,  read  the  following  documents:
 
Overview  of  In
-­‐
app  Billing
 
Learn  how  the  service  wor
ks  and  what  a  typical  in
-­‐
app  billing  implementation  looks  like.
 
Implementing  In
-­‐
app  Billing
 
Use  this  step
-­‐
by
-­‐
step  guide  to  start  incorporating  in
-­‐
app  billing  into  your
 
application.
 
Security  and  Design
 
Review  these  best  practices  to  help  ensure  that  your  in
-­‐
app  billing  implementation  is  secure  and  well  
designed.
 
Testing  In
-­‐
app  Billing
 
Understand  how  the  in
-­‐
app  billing  test  tools  work  and  learn  how  to  test  your  in
-­‐
app  billing  
implementation.
 
Administering  In
-­‐
app  Billing
 
Learn  how  to  set  up  your  product  list,  register  test  accounts,  and  handle  refunds.
 
In
-­‐
app  Billing  Reference
 
Get  detailed  information  about  Android  Market  response  codes  and  the  in
-­‐
app  billing  interface.
 
In
-­‐
app  Billing  Overview
 
Android  Market  In
-­‐
app  Billing  is  an  Android  Market  service  that  provides  checkout  processing  for  in
-­‐
app  purchases.  To  use  the  service,  
your  application  sends  a  billing  request  for  a  specific  in
-­‐
app  
product.  The  service  then  handles  all  of  the  checkout  details  for  the  transaction,  including  requesting  
and  validating  the  form  of  payment  and  processing  the  financial  transaction.  When  the  che
ckout  
process  is  complete,  the  service  sends  your  application  the  purchase  details,  such  as  the  order  
number,  the  order  date  and  time,  and  the  price  paid.  At  no  point  does  your  application  have  to  handle  
any  financial  transactions;  that  role  is  provided  by
 
Android  Market

s  in
-­‐
app  billing  service.
 
In
-­‐
app  Billing  Architecture
 
In
-­‐
app  billing  uses  an  asynchronous  message  loop  to  convey  billing  requests  and  billing  responses  
between  your  application  and  the  Android  Market  server.  In  practice,  your  application  ne
ver  directly  
communicates  with  the  Android  Market  server  (see  figure  1).  Instead,  your  application  sends  billing  
requests  to  the  Android  Market  application  over  interprocess  communication  (IPC)  and  receives  
purchase  responses  from  the  Android  Market  applic
ation  in  the  form  of  asynchronous  broadcast  
intents.  Your  application  does  not  manage  any  network  connections  between  itself  and  the  Android  
Market  server  or  use  any  special  APIs  from  the  Android  platform.
 
Some  in
-­‐
app  billing  implementations  may  also  use  a
 
private  remote  server  to  deliver  content  or  
validate  transactions,  but  a  remote  server  is  not  required  to  implement  in
-­‐
app  billing.  A  remote  server  
can  be  useful  if  you  are  selling  digital  content  that  needs  to  be  delivered  to  a  user

s  device,  such  as  
med
ia  files  or  photos.  You  might  also  use  a  remote  server  to  store  users

 
transaction  history  or  
perform  various  in
-­‐
app  billing  security  tasks,  such  as  signature  verification.  Although  you  can  handle  all  
security
-­‐
related  tasks  in  your  application,  performing  those  tasks  on  a  remote  server  is  recommended  
because  it  helps  make  yo
ur  application  less  vulnerable  to  security  attacks.
 

Figure  1.
 
Your  application  sends  and  receives  billing  messages  through  the  Android  Market  
application,  which  handles  all  communication  with  the  Android  Market  server.
 
A  typical  in
-­‐
app  billing  implementa
tion  relies  on  three  components:
 


A  
Service
 
(named  
BillingService
 
in  the  sample  application),  which  processes  purchase  
messages  from  the  application  and  sends  billing  requests  t
o  Android  Market

s  in
-­‐
app  billing  
service.
 


A  
BroadcastReceiver
 
(named  
BillingReceiver
 
in  the  sample  application),  which  
receives  all  asynchronous  billing  response
s  from  the  Android  Market  application.
 


A  security  component  (named  
Security
 
in  the  sample  application),  which  performs  security
-­‐
related  tasks,  such  as  signature  verification  and  nonce  generation.  For  more  information  about  
in
-­‐
app  billing  security,  see  
Secu
rity  controls
 
later  in  this  document.
 
You  may  also  want  to  incorporate  two  other  components  to  support  in
-­‐
app  billing:
 


A  response  
Handler
 
(named  
ResponseHandler
 
in  the  sample  application),  which  provides  
application
-­‐
specific  processing  of  purchase  notifications,  errors,  and  other  status  messages.
 


An  observer  (named  
PurchaseObserver
 
in  the  sample  application),  which  is  responsible  for  
sending  callbacks  to  your  app
lication  so  you  can  update  your  user  interface  with  purchase  
information  and  status.
 
In  addition  to  these  components,  your  application  must  provide  a  way  to  store  information  about  
users

 
purchases  and  some  sort  of  user  interface  that  lets  users  select  ite
ms  to  purchase.  You  do  not  
need  to  provide  a  checkout  user  interface.  When  a  user  initiates  an  in
-­‐
app  purchase,  the  Android  
Market  application  presents  the  checkout  user  interface  to  your  user.  When  the  user  completes  the  
checkout  process,  your  application
 
resumes.
 
In
-­‐
app  Billing  Messages
 
When  the  user  initiates  a  purchase,  your  application  sends  billing  messages  to  Android  Market

s  in
-­‐
app  
billing  service  (named  
MarketBillingService
)  using  simple  IPC  method  calls.  The  Android  
Market  application  responds  to  
all  billing  requests  synchronously,  providing  your  application  with  
status  notifications  and  other  information.  The  Android  Market  application  also  responds  to  some  
billing  requests  asynchronously,  providing  your  application  with  error  messages  and  detaile
d  
transaction  information.  The  following  section  describes  the  basic  request
-­‐
response  messaging  that  
takes  place  between  your  application  and  the  Android  Market  application.
 
In
-­‐
app  billing  requests
 
Your  application  sends  in
-­‐
app  billing  requests  by  invoking
 
a  single  IPC  method  
(
sendBillingRequest()
),  which  is  exposed  by  the  
MarketBillingService
 
interface.  This  
interface  is  defined  in  an  
Android  Interface  Definition  Language
 
file  
(
I
MarketBillingService.aidl
).  You  can  
download
 
this  AIDL  file  with  the  in
-­‐
app  billing  sample  
application.
 
The  
sendBillingRequest()
 
method  has  a  sin
gle  
Bundle
 
parameter.  The  Bundle  that  you  deliver  
must  include  several  key
-­‐
value  pairs  that  specify  various  parameters  for  the  request,  such  as  the  type  
of  billing  request  you  ar
e  making,  the  item  that  is  being  purchased,  and  the  application  that  is  making  
the  request.  For  more  information  about  the  Bundle  keys  that  are  sent  with  a  request,  see  
In
-­‐
app  
Billing  Service  Interface
.
 
One  of  the  most  important  keys  that  every  request  Bundle  must  have  is  the  
BILLING_REQUEST
 
key.  
This  key  lets  you  specify  the  type  of  billing  request  you  are  making.  Android  Market

s  in
-­‐
app  billing  
service  supports  the  following  five  types  of  billing  requests:
 


CHECK_BILLING_SUPPORTED
This
 
request  verifies  that  the  Android  Market  application  
supports  in
-­‐
app  billing.  You  usually  send  this  request  when  your  application  first  starts  up.  This  
request  is  useful  if  you  want  to  enable  or  disable  certain  UI  features  that  are  relevant  only  to  in
-­‐
app
 
billing.
 


REQUEST_PURCHASE
This  request  sends  a  purchase  message  to  the  Android  Market  
application  and  is  the  foundation  of  in
-­‐
app  billing.  You  send  this  request  when  a  user  indicates  
that  he  or  she  wants  to  purchase  an  item  in  your  application.  Android  Mar
ket  then  handles  the  
financial  transaction  by  displaying  the  checkout  user  interface.
 


GET_PURCHASE_INFORMATION
This  request  retrieves  the  details  of  a  purchase  state  change.  
A  purchase  changes  state  when  a  requested  purchase  is  billed  successfully  or  when  a
 
user  
cancels  a  transaction  during  checkout.  It  can  also  occur  when  a  previous  purchase  is  refunded.  
Android  Market  notifies  your  application  when  a  purchase  changes  state,  so  you  only  need  to  
send  this  request  when  there  is  transaction  information  to  retr
ieve.
 


CONFIRM_NOTIFICATIONS
This  request  acknowledges  that  your  application  received  the  
details  of  a  purchase  state  change.  Android  Market  sends  purchase  state  change  notifications  
to  your  application  until  you  confirm  that  you  received  them.
 


RESTORE_TRANS
ACTIONS
This  request  retrieves  a  user

s  transaction  status  for  
managed  
purchases
.  You  should  send  this  request  only  when  you  need  to  retrieve  a  u
ser

s  transaction  
status,  which  is  usually  only  when  your  application  is  reinstalled  or  installed  for  the  first  time  on  
a  device.
 
In
-­‐
app  Billing  Responses
 
The  Android  Market  application  responds  to  in
-­‐
app  billing  requests  with  both  synchronous  and  
asynchro
nous  responses.  The  synchronous  response  is  a  
Bundle
 
with  the  following  three  keys:
 


RESPONSE_CODE
This  key  provides  status  information  and  error  information  about  a  request.
 


PURCH
ASE_INTENT
This  key  provides  a  
PendingIntent
,  which  you  use  to  launch  the  
checkout  activity.
 


REQUEST_ID
This  key  provides  you  with  a  request  identifier,  which  you  can  use  t
o  match  
asynchronous  responses  with  requests.
 
Some  of  these  keys  are  not  relevant  to  every  request.  For  more  information,  see  
Messaging  sequence
 
later  in  this  document.
 
The  asynchronous  response  messages  are  sent  in  the  form  of  individual  broadcast  intents
 
and  include  
the  following:
 


com.android.vending.billing.RESPONSE_CODE
This  response  contains  an  Android  
Market  server  response  code,  and  is  sent  after  you  make  an  in
-­‐
app  billing  request.  A  server  
response  code  can  indicate  that  a  billing  request  was  success
fully  sent  to  Android  Market  or  it  
can  indicate  that  some  error  occurred  during  a  billing  request.  This  response  is  
not
 
used  to  
report  any  purchase  state  changes  (such  as  refund  or  purchase  information).  For  more  
information  about  the  response  codes  that  a
re  sent  with  this  response,  see  
Server  Response  
Codes  for  In
-­‐
app  Billing
.
 


com.android.vending.billing.IN_APP_NOTIFY
This
 
response  indicates  that  a  
purchase  has  changed  state,  which  means  a  purchase  succeeded,  was  canceled,  or  was  
refunded.  This  response  contains  one  or  more  notification  IDs.  Each  notification  ID  
corresponds  to  a  specific  server
-­‐
side  message,  and  each  messag
es  contains  information  about  
one  or  more  transactions.  After  your  application  receives  an  
IN_APP_NOTIFY
 
broadcast  
intent,  you  send  a  
GET_PURCHASE_INFORMATION
 
request  with  the  notification  IDs  to  
retrieve  message  details.
 


com.android.vending.billing.PURCHA
SE_STATE_CHANGED
This  response  contains  
detailed  information  about  one  or  more  transactions.  The  transaction  information  is  contained  
in  a  JSON  string.  The  JSON  string  is  signed  and  the  signature  is  sent  to  your  application  along  
with  the  JSON  string  (unenc
rypted).  To  help  ensure  the  security  of  your  in
-­‐
app  billing  
messages,  your  application  can  verify  the  signature  of  this  JSON  string.
 
The  JSON  string  that  is  returned  with  the  
PURCHASE_STATE_CHANGED
 
intent  provides  your  
application  with  the  details  of  one  o
r  more  billing  transactions.  An  example  of  this  JSON  string  is  
shown  below:
 
{  

nonce

 
:  1836535032137741465,
 

orders

 
:
 
{  

notificationId

 
:  

android.test.purchased

,
 

orderId

 
:  

transactionId.android.test.purchased

,
 

packageName

 
:  

com.example.dungeons

,
 

productId

 
:  

android.test.purchased

,
 

developerPayload

 
:  

bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ

,
 

purchaseTime

 
:  1290114783411,
 

purchaseState

 
:  0  }
 
}

For  more  information  about  the  fields  in  this  JSON  string,  see  
In
-­‐
app  Billing  Broadcast  Intents
.
 
Messaging  sequence
 
The  messaging  sequence  for  a  typical  purchase  request  is  shown  in  figure  2.  Request  types  for  e
ach  
sendBillingRequest()
 
method  are  shown  in  
bold
,  broadcast  intents  are  shown  in  
italic
.  For  
clarity,  figure  2  does  not  show  the  
RESPONSE_CODE
 
broadcast  intents  that  are  sent  for  every  
request.
 
The  basic  message  sequence  for  an  in
-­‐
app  purchase  request  is  
as  follows:
 
1.

Your  application  sends  a  purchase  request  (
REQUEST_PURCHASE
 
type),  specifying  a  product  
ID  and  other  parameters.
 
2.

The  Android  Market  application  sends  your  application  a  Bundle  with  the  following  keys:  
RESPONSE_CODE
,  
PURCHASE_INTENT
,  and  
REQUEST
_ID
.  The
PURCHASE_INTENT
 
key  
provides  a  
PendingIntent
,  which  your  application  uses  to  start  the  checkout  UI  for  the  
given  product  ID.
 
3.

Your  application  launches  the  pending  intent,  which  launches  the  checkout  UI.
Note:
 
You  must  
launch  the  pending  intent  from  an  activity  context  and  not  an  application  context.
 
4.

When  the  checkout  flow  finishes  (that  is,  the  user  successfully  purchases  the  ite
m  or  cancels  
the  purchase),  Android  Market  sends  your  application  a  notification  message  (an  
IN_APP_NOTIFY
 
broadcast  intent).  The  notification  message  includes  a  notification  ID,  which  
references  the  transaction.
 
5.

Your  application  requests  the  transaction  i
nformation  by  sending  a  
GET_PURCHASE_STATE_CHANGED
 
request,  specifying  the  notification  ID  for  the  transaction.
 
6.

The  Android  Market  application  sends  a  Bundle  with  a  
RESPONSE_CODE
 
key  and  a  
REQUEST_ID
 
key.
 
7.

Android  Market  sends  the  transaction  information  to
 
your  application  in  a  
PURCHASE_STATE_CHANGED
 
broadcast  intent.
 
8.

Your  application  confirms  that  you  received  the  transaction  information  for  the  given  
notification  ID  by  sending  a  confirmation  message  (
CONFIRM_NOTIFICATIONS
 
type),  
specifying  the  notificatio
n  ID  for  which  you  received  transaction  information.
 
9.

The  Android  Market  application  sends  your  application  a  Bundle  with  a  
RESPONSE_CODE
 
key  
and  a  
REQUEST_ID
 
key.
 

Figure  2.
 
Message  sequence  for  a  purchase  request.
 
Keep  in  mind,  you  must  send  a  confirmati
on  when  you  receive  transaction  information  from  Android  
Market  (step  8  in  figure  2).  If  you  don

t  send  a  confirmation  message,  Android  Market  will  continue  
sending  
IN_APP_NOTIFY
 
messages  for  the  transactions  you  have  not  confirmed.  As  a  best  practice,  
you
 
should  not  send  a  
CONFIRM_NOTIFICATIONS
 
request  for  a  purchased  item  until  you  have  
delivered  the  item  to  the  user.  This  way,  if  your  application  crashes  or  something  else  prevents  your  
application  from  delivering  the  product,  your  application  will  still  
receive  an  
IN_APP_NOTIFY
 
broadcast  intent  from  Android  Market  indicating  that  you  need  to  deliver  the  product.  Also,  as  a  best  
practice,  your  application  must  be  able  to  handle  
IN_APP_NOTIFY
 
messages  that  contain  multiple  
orders.
 
The  messaging  sequence  for  a  restore  transaction  request  is  shown  in  figure  3.  Request  types  for  each  
sendBillingRequest()
 
method  are  shown  in  
bold
,  broadcast  intents  are  shown  in  
italic
.  For  
clarity,  figure  3  does  not  show  the  
RESPONSE_CODE
 
broadcast  inte
nts  that  are  sent  for  every  
request.
 

Figure  3.
 
Message  sequence  for  a  restore  transactions  request.
 
The  request  triggers  three  responses.  The  first  is  a  
Bundle
 
with  a  
RESPONSE_CODE
 
key  and  a  
REQUEST_ID
 
key.  Next,  the  Android  Market  application  sends  a  
RESPONSE_CODE
 
broadcast  intent,  
which  provides  status  information  or  error  information  about  the  request.  As  always,  the  
RESPONSE_CODE
 
message  references  a  specific  reques
t  ID,  so  you  can  determine  which  request  a  
RESPONSE_CODE
 
message  pertains  to.
 
The  
RESTORE_TRANSACTIONS
 
request  type  also  triggers  a  
PURCHASE_STATE_CHANGED
 
broadcast  intent,  which  contains  the  same  type  of  transaction  information  that  is  sent  during  a  
purch
ase  request,  although  you  do  not  need  to  respond  to  this  intent  with  a  
CONFIRM_NOTIFICATIONS
 
message.
 
Note:
 
You  should  use  the  
RESTORE_TRANSACTIONS
 
request  type  only  when  your  application  is  
installed  for  the  first  time  on  a  device  or  when  your  application  has  been  removed  from  a  device  and  
reinstalled.
 
The  messaging  sequence  for  checking  whether  in
-­‐
app  billing  is  supported  is  shown  in  figure  4.  The  
request  type  for  the  
sendBillingRequest()
 
method  is  shown  in  
bold
.
 

Figure  4.
 
Message  sequence  for  checking  whether  in
-­‐
app  billing  is  supported.
 
The  synchronous  response  for  a  
CHECK_BILLING_SUPPORTED
 
request  provides  a  Bundle  with  a  
server  response  code.  
A  
RESULT_OK
 
response  code  indicates  that  in
-­‐
app  billing  is  supported;  a  
RESULT_BILLING_UNAVAILABLE
 
response  code  indicates  that  in
-­‐
app  billing  is  unavailable  because  
the  API  version  you  specified  is  unrecognized  or  the  user  is  not  eligible  to  make  in
-­‐
app  p
urchases  (for  
example,  the  user  resides  in  a  country  that  does  not  allow  in
-­‐
app  billing).  A  
SERVER_ERROR
 
can  also  
be  returned,  indicating  that  there  was  a  problem  with  the  Android  Market  server.
 
Handling  IN_APP_NOTIFY  messages
 
Usually,  your  application  rec
eives  an  
IN_APP_NOTIFY
 
broadcast  intent  from  Android  Market  in  
response  to  a  
REQUEST_PURCHASE
 
message  (see  figure  2).  The  
IN_APP_NOTIFY
 
broadcast  intent  
informs  your  application  that  the  state  of  a  requested  purchase  has  changed.  To  retrieve  the  details  of
 
that  purchase,  your  application  sends  a  
GET_PURCHASE_INFORMATION
 
request.  Android  Market  
responds  with  a  
PURCHASE_STATE_CHANGED
 
broadcast  intent,  which  contains  the  details  of  the  
purchase  state  change.  Your  application  then  sends  a  
CONFIRM_NOTIFICATIONS
 
message,  
informing  Android  Market  that  you  have  received  the  purchase  state  change  information.
 
In  some  special  cases,  you  may  receive  multiple  
IN_APP_NOTIFY
 
messages  even  though  you  have  
confirmed  receipt  of  the  purchase  information,  or  you  may  receive  
IN
_APP_NOTIFY
 
messages  for  a  
purchase  change  even  though  you  never  initiated  the  purchase.  Your  application  must  handle  both  of  
these  special  cases.
 
Handling  multiple  IN_APP_NOTIFY  messages
 
When  Android  Market  receives  a  
CONFIRM_NOTIFICATIONS
 
message  for  a  g
iven  
PURCHASE_STATE_CHANGED
 
message,  it  usually  stops  sending  
IN_APP_NOTIFY
 
intents  for  that  
PURCHASE_STATE_CHANGED
 
message.  Sometimes,  however,  Android  Market  may  send  repeated  
IN_APP_NOTIFY
 
intents  for  a  
PURCHASE_STATE_CHANGED
 
message  even  though  your  application  
has  sent  a  
CONFIRM_NOTIFICATIONS
 
message.  This  can  occur  if  a  device  loses  network  
connectivity  while  you  are  sending  the  
CONFIRM_NOTIFICATIONS
 
message.  In  this  case,  Android  
Market  might  not  receive  your  
CONFIRM_NOTIF
ICATIONS
 
message  and  it  could  send  multiple  
IN_APP_NOTIFY
 
messages  until  it  receives  acknowledgement  that  you  received  the  transaction  
message.  Therefore,  your  application  must  be  able  to  recognize  that  the  subsequent  
IN_APP_NOTIFY
 
messages  are  for  a  previ
ously  processed  transaction.  You  can  do  this  by  checking  
the  
orderID
 
that

s  contained  in  the  JSON  string  because  every  transaction  has  a  unique  
orderId
.
 
Handling  refunds  and  other  unsolicited  IN_APP_NOTIFY  messages
 
There  are  two  cases  where  your  applicatio
n  may  receive  
IN_APP_NOTIFY
 
broadcast  intents  even  
though  your  application  has  not  sent  a  
REQUEST_PURCHASE
 
message.  Figure  5  shows  the  messaging  
sequence  for  both  of  these  cases.  Request  types  for  each  
sendBillingRequest()
 
method  are  
shown  in  
bold
,  broadca
st  intents  are  shown  in  
italic
.  For  clarity,  figure  5  does  not  show  the  
RESPONSE_CODE
 
broadcast  intents  that  are  sent  for  every  request.
 

Figure  5.
 
Message  sequence  for  refunds  and  other  unsolicited  IN_APP_NOTIFY  messages.
 
In  the  first  case,  your  applicat
ion  may  receive  an  
IN_APP_NOTIFY
 
broadcast  intent  when  a  user  has  
your  application  installed  on  two  (or  more)  devices  and  the  user  makes  an  in
-­‐
app  purchase  from  one  
of  the  devices.  In  this  case,  Android  Market  sends  an  
IN_APP_NOTIFY
 
message  to  the  second  
device,  informing  the  application  that  there  is  a  purchase  state  change.  Your  application  can  handle  
this  message  the  same  way  it  handles  the  response  from  an  application
-­‐
initiated  
REQUEST_PURCHASE
 
message,  so  that  ultimately  your  ap
plication  receives  a  
PURCHASE_STATE_CHANGED
 
broadcast  intent  message  that  includes  information  about  the  item  
that  has  been  purchased.  This  applies  only  to  items  that  have  their  
purchase  type
 
set  to  

managed  per  
user  account.

 
In  the  second  case,  your  application  can  receive  an  
IN_APP_NOTIFY
 
broadcast  intent  when  Android  
Market  receives  a  refund  notification  from  Google  Checkout.  In  this  case,  And
roid  Market  sends  an  
IN_APP_NOTIFY
 
message  to  your  application.  Your  application  can  handle  this  message  the  same  
way  it  handles  responses  from  an  application
-­‐
initiated  
REQUEST_PURCHASE
 
message  so  that  
ultimately  your  application  receives  a  
PURCHASE_STATE_
CHANGED
 
message  that  includes  
information  about  the  item  that  has  been  refunded.  The  refund  information  is  included  in  the  JSON  
string  that  accompanies  the  
PURCHASE_STATE_CHANGED
 
broadcast  intent.  Also,  the  
purchaseState
 
field  in  the  JSON  string  is  set  to  
2.
 
Important:
 
You  cannot  use  the  Google  Checkout  API  to  issue  refunds  or  cancel  in
-­‐
app  billing  
transactions.  You  must  do  this  manually  through  your  Google  Checkout  merchant  account.  However,  
you  can  use  the  Google  Checkout  API  to  retrieve  order  information
.
 
Security  Controls
 
To  help  ensure  the  integrity  of  the  transaction  information  that  is  sent  to  your  application,  Android  
Market  signs  the  JSON  string  that  is  contained  in  the  
PURCHASE_STATE_CHANGED
 
broadcast  intent.  
Android  Market  uses  the  private  key  tha
t  is  associated  with  your  publisher  account  to  create  this  
signature.  The  publisher  site  generates  an  RSA  key  pair  for  each  publisher  account.  You  can  find  the  
public  key  portion  of  this  key  pair  on  your  account

s  profile  page.  It  is  the  same  public  key  th
at  is  used  
with  Android  Market  licensing.
 
When  Android  Market  signs  a  billing  response,  it  includes  the  signed  JSON  string  (unencrypted)  and  
the  signature.  When  your  application  receives  this  signed  response  you  can  use  the  public  key  portion  
of  your  RSA  k
ey  pair  to  verify  the  signature.  By  performing  signature  verification  you  can  help  detect  
responses  that  have  been  tampered  with  or  that  have  been  spoofed.  You  can  perform  this  signature  
verification  step  in  your  application;  however,  if  your  application  c
onnects  to  a  secure  remote  server  
then  we  recommend  that  you  perform  the  signature  verification  on  that  server.
 
In
-­‐
app  billing  also  uses  nonces  (a  random  number  used  once)  to  help  verify  the  integrity  of  the  
purchase  information  that

s  returned  from  Androi
d  Market.  Your  application  must  generate  a  nonce  
and  send  it  with  a  
GET_PURCHASE_INFORMATION
 
request  and  a  
RESTORE_TRANSACTIONS
 
request.  When  Android  Market  receives  the  request,  it  adds  the  nonce  to  the  JSON  string  that  
contains  the  transaction  informatio
n.  The  JSON  string  is  then  signed  and  returned  to  your  application.  
When  your  application  receives  the  JSON  string,  you  need  to  verify  the  nonce  as  well  as  the  signature  
of  the  JSON  string.
 
For  more  information  about  best  practices  for  security  and  design,
 
see  
Security  and  Design
.
 
In
-­‐
app  Billing  Requirements  and  Limitations
 
Before  you  get  started  with  in
-­‐
app  billing,  be  sure  to  review  the  following  requirements  and
 
limitations.
 


In
-­‐
app  billing  can  be  implemented  only  in  applications  that  you  publish  through  Android  
Market.
 


You  must  have  a  Google  Checkout  Merchant  account  to  use  Android  Market  In
-­‐
app  Billing.
 


If  your  device  is  running  Android  3.0,  in
-­‐
app  billing  requi
res  version  5.0.12  (or  higher)  of  the  
MyApps  application.  If  your  device  is  running  any  other  version  of  Android,  in
-­‐
app  billing  
requires  version  2.3.4  (or  higher)  of  the  Android  Market  application.
 


An  application  can  use  in
-­‐
app  billing  only  if  the  device  
is  running  Android  1.6  (API  level  4)  or  
higher.
 


You  can  use  in
-­‐
app  billing  to  sell  only  digital  content.  You  cannot  use  in
-­‐
app  billing  to  sell  
physical  goods,  personal  services,  or  anything  that  requires  physical  delivery.
 


Android  Market  does  not  provide  
any  form  of  content  delivery.  You  are  responsible  for  
delivering  the  digital  content  that  you  sell  in  your  applications.
 


You  cannot  implement  in
-­‐
app  billing  on  a  device  that  never  connects  to  the  network.  To  
complete  in
-­‐
app  purchase  requests,  a  device  must
 
be  able  to  access  the  Android  Market  server  
over  the  network.
 
For  more  information  about  in
-­‐
app  billing  requirements,  see  
In
-­‐
App  Billing  Availability  and  Policies
.
 
Implementin
g  In
-­‐
app  Billing
 
Android  Market  In
-­‐
app  Billing  provides  a  straightforward,  simple  interface  for  sending  in
-­‐
app  billing  
requests  and  managing  in
-­‐
app  billing  transactions  using  Android  Market.  This  document  helps  you  
implement  in
-­‐
app  billing  by  stepping  thro
ugh  the  primary  implementation  tasks,  using  the  in
-­‐
app  
billing  sample  application  as  an  example.
 
Before  you  implement  in
-­‐
app  billing  in  your  own  application,  be  sure  that  you  read  
Overview  of  In
-­‐
app  
Billing
 
and  
Security  and  Design
.  These  documents  provide  background  information  that  will  make  it  
easier  for  you  to  implement  in
-­‐
ap
p  billing.
 
To  implement  in
-­‐
app  billing  in  your  application,  you  need  to  do  the  following:
 
1.

Download  the  in
-­‐
app  billing  sample  application
.
 
2.

Add  the  IMarketBillingService.aidl  file
 
to  your  project.
 
3.

Update  your  AndroidManifest.xml  file
.
 
4.

Create  a  Service
 
and  bi
nd  it  to  the  
MarketBillingService
 
so  your  application  can  send  
billing  requests  and  receive  billing  responses  from  the  Android  Market  application.
 
5.

Create  a  BroadcastReceiver
 
to  handle  broadcast  intents  from  the  Android  Market  application.
 
6.

Create  a  security
 
processing  component
 
to  verify  the  integrity  of  the  transaction  messages  
that  are  sent  by  Android  Market  .
 
7.

Modify  your  application  code
 
to  support  in
-­‐
app  billing.
 
Downloading  the  Sample  Application
 
The  in
-­‐
app  billing  sample  application  shows  you  how  to  pe
rform  several  tasks  that  are  common  to  all  
Android  Market  in
-­‐
app  billing  implementations,  including:
 
1.

Sending  in
-­‐
app  billing  requests  to  the  Android  Market  application.
 
2.

Handling  synchronous  responses  from  the  Android  Market  application.
 
3.

Handling  broadcast  i
ntents  (asynchronous  responses)  from  the  Android  Market  application.
 
4.

Using  in
-­‐
app  billing  security  mechanisms  to  verify  the  integrity  of  billing  responses.
 
5.

Creating  a  user  interface  that  lets  users  select  items  for  purchase.
 
The  sample  application  includes
 
an  application  file  (
Dungeons.java
),  the  AIDL  file  for  the  
MarketBillingService
 
(
IMarketBillingService.aidl
),  and  several  classes  that  
demonstrate  in
-­‐
app  billing  messaging.  It  also  includes  a  class  that  demonstrates  basic  security  
tasks,  such  as  signature
 
verification.
 
Table  1  lists  the  source  files  that  are  included  with  the  sample  application.
 


Table  1.
 
In
-­‐
app  billing  sample  application  source  files.
 
File

Description

IMarketBillingService.aidl

Android Interface Definition Library (AIDL) file that
defines the IPC interface to Android Market

s in
-
app
billing service (
MarketBillingService
).

Dungeons.java

Sample application file that provides a UI for making
purchases and displaying purchase history.

PurchaseDatabase.java

A local database for storing

purchase information.

BillingReceiver.java

A
BroadcastReceiver

that receives asynchronous
response messages (broadcast intents) from Android
Market. Forwards al
l messages to the
BillingService
.

BillingService.java

A
Service

that sends messages to Android Market on
behalf of the application by connecting (binding) to the
MarketBilling
Service
.

ResponseHandler.java

A
Handler

that contains methods for updating the
purchases database and the UI.

PurchaseObserver.java

An abstract class for observing changes
related to
purchases.

Security.java

Provides various security
-
related methods.

Consts.java

Defines various Android Market constants and sample
application constants. All constants that are defined by
Android Market must be defined the same way in your
application.

Base64.java and
Base64DecoderException.java

Provides conversion services from binary to Base64
encoding. The
Security

class relies on these utility
classes.

The  in
-­‐
app  billing  sample  application  is  available  as  a  downloadable  component  of  th
e  Android  SDK.  To  
download  the  sample  application  component,  launch  the  Android  SDK  and  AVD  Manager  and  then  
select  the  

Google  Market  Billing  package

 
component  (see  figure  1),  and  click  
Install  Selected
 
to  
begin  the  download.
 

Figure  1.
 
The  Google  Marke
t  Billing  package  contains  the  sample  application  and  the  AIDL  file.
 
When  the  download  is  complete,  the  Android  SDK  and  AVD  Manager  saves  the  component  into  the  
following  directory:
 
<sdk>/extras/google/market_billing/

If  you  want  to  see  an  end
-­‐
to
-­‐
end  demon
stration  of  in
-­‐
app  billing  before  you  integrate  in
-­‐
app  billing  
into  your  own  application,  you  can  build  and  run  the  sample  application.  Building  and  running  the  
sample  application  involves  three  tasks:
 


Configuring  and  building  the  sample  application.
 


Uploading  the  sample  application  to  Android  Market.
 


Setting  up  test  accounts  and  running  the  sample  application.
 
Note:
 
Building  and  running  the  sample  application  is  necessary  only  if  you  want  to  see  a  
demonstration  of  in
-­‐
app  billing.  If  you  do  not  want  to
 
run  the  sample  application,  you  can  skip  to  the  
next  section,  
Adding  the  AIDL  file  to  your  project
.
 
Configuring  and  building  the  sample  application
 
Before  you  can  run  the  sample  application,  you  need  to  configure  it  and  build  it  by  doing  the  
following:
 


Add  your  Android  Market  public  key  to  the  sample  application  code.
This  enables  the  
application  to  verify  the  signature  of  the  transaction  information  that  is  returned  from  Android  
Market.  To  add  your  public  key  to  the  sample  application  code,  do  the  follow
ing:
 

Log  in  to  your  Android  Market  
publisher  account
.
 

On  the  upper  left  part  of  the  page,  under  your  name,  click  
Edit  Profile
.
 

On  the  Edit  Profile  page,  scroll  down  to  the  
Licensing  &  In
-­‐
app  Billing
 
panel.
 

Copy  your  public  key.
 
Open  
src/com/example/dungeons/Security.java
 
in  the  editor  of  your  choice.You  
can  find  this  file  in  the  sample  application

s  project  folder.
 
Add your public key to the following line of code:
String  base64EncodedPublicKey  =  

your  
public
 
key  here

;


Save  the  file.
 




Change  the  package  name  of  the  sample  application.
The  current  package  name  is  
com.example.dungeons
.  Android  Market  does  not  let  you  upload  applications  with  
package  names  that  contain  
com.example
,  so  you  must      change  the  
package  name  to  
something  else.
 


Build  the  sample  application  in  release  mode  and  sign  it.
To  learn  how  to  build  and  sign  
applications,  see  
Building  and  Running
.
 
Uploading  the  
sample  application
 
After  you  build  a  release  version  of  the  sample  application  and  sign  it,  you  need  to  upload  it  as  a  draft  
to  the  Android  Market  publisher  site.  You  also  need  to  create  a  product  list  for  the  in
-­‐
app  items  that  
are  available  for  purchase  i
n  the  sample  application.  The  following  instructions  show  you  how  to  do  
this.
 


Upload  the  release  version  of  the  sample  application  to  Android  Market.
Do  not  publish  the  
sample  application;  leave  it  as  an  unpublished  draft  application.  The  sample  application
 
is  for  
demonstration  purposes  only  and  should  not  be  made  publicly  available  on  Android  Market.  To  
learn  how  to  upload  an  application  to  Android  Market,  see  
Uploading  applicatio
ns
.
 


Create  a  product  list  for  the  sample  application.
The  sample  application  lets  you  purchase  two  
items:  a  two
-­‐
handed  sword  (
sword_001
)  and  a  potion  (
potion_001
).  We  recommend  that  
you  set  up  your  product  list  so  that  
sword_001
 
has  a  purchase  type  of  

Mana
ged  per  user  
account

 
and  
potion_001
 
has  a  purchase  type  of  

Unmanaged

 
so  you  can  see  how  these  
two  purchase  types  behave.  To  learn  how  to  set  up  a  product  list,  see  
Creating  a  Product  
List
.  
Note:
 
You  must  publish  the  items  in  your  product  list  (
sword_001
 
and  
potion_001
)  
even  though  you  are  not  publishing  the  sample  application.  Also,  you  must  have  a  Google  
Checkout  Merchant  account  to  add  items  to  
the  sample  application

s  product  list.
 
Running  the  sample  application
 
You  cannot  run  the  sample  application  in  the  emulator.  You  must  install  the  sample  application  onto  a  
device  to  run  it.  To  run  the  sample  application,  do  the  following:
 


Make  sure  you  hav
e  at  least  one  test  account  registered  under  your  Android  Market  publisher  
account.
You  cannot  purchase  items  from  yourself  (Google  Checkout  prohibits  this),  so  you  
need  to  create  at  least  one  test  account  that  you  can  use  to  purchase  items  in  the  sample  
ap
plication.  To  learn  how  to  set  up  a  test  account,  see  
Setting  up  Test  Accounts
.
 


Verify  that  your  device  is  running  a  supported  version  of  the  
Android  Market  application  or  
the  MyApps  application.
If  your  device  is  running  Android  3.0,  in
-­‐
app  billing  requires  version  
5.0.12  (or  higher)  of  the  MyApps  application.  If  your  device  is  running  any  other  version  of  
Android,  in
-­‐
app  billing  requires  versio
n  2.3.4  (or  higher)  of  the  Android  Market  application.  To  
learn  how  to  check  the  version  of  the  Android  Market  application,  see  
Updating  Android  
Market
.
 


Install  the  application  onto  your  device.
Even  though  you  uploaded  the  application  to  Android  
Market,  the  application  is  not  published,  so  you  cannot  download  it  from  Android  Market  to  a  
device.  Instead,  you  must  install  the  application  onto  your  device.  To
 
learn  how  to  install  an  
application  onto  a  device,  see  
Running  on  a  device
.
 


Make  one  of  your  test  accounts  the  primary  account  on  your  device
.
The  primary  account  on  
your  device  must  be  one  of  the  
test  accounts
 
that  you  registered  on  the  Android  Market  site.  If  
the  primary  account  on  y
our  device  is  not  a  test  account,  you  must  do  a  factory  reset  of  the  
device  and  then  sign  in  with  one  of  your  test  accounts.  To  perform  a  factory  reset,  do  the  
following:
 

Open  Settings  on  your  device.
 

Touch  
Privacy
.
 

Touch  Factory  data  reset.
 

Touch  Reset  ph
one.
 

After  the  phone  resets,  be  sure  to  sign  in  with  one  of  your  test  accounts  during  the  
device  setup  process.
 


Run  the  application  and  purchase  the  sword  or  the  potion.
When  you  use  a  test  account  to  
purchase  items,  the  test  account  is  billed  through  Googl
e  Checkout  and  your  Google  Checkout  
Merchant  account  receives  a  payout  for  the  purchase.  Therefore,  you  may  want  to  refund  
purchases  that  are  made  with  test  accounts,  otherwise  the  purchases  will  show  up  as  actual  
payouts  to  your  merchant  account.
 
Note
:  De
bug  log  messages  are  turned  off  by  default  in  the  sample  application.  You  can  turn  them  on  
by  setting  the  variable  
DEBUG
 
to  
true
 
in  the  
Consts.java
 
file.
 
Adding  the  AIDL  file  to  your  project
 
The  sample  application  contains  an  Android  Interface  Definition  L
anguage  (AIDL)  file,  which  defines  
the  interface  to  Android  Market

s  in
-­‐
app  billing  service  (
MarketBillingService
).  When  you  add  
this  file  to  your  project,  the  Android  build  environment  creates  an  interface  file  
(
IMarketBillingService.java
).  You  can  then  
use  this  interface  to  make  billing  requests  by  
invoking  IPC  method  calls.
 
If  you  are  using  the  ADT  plug
-­‐
in  with  Eclipse,  you  can  just  add  this  file  to  your  
/src
 
directory.  Eclipse  
will  automatically  generate  the  interface  file  when  you  build  your  project  (
which  should  happen  
immediately).  If  you  are  not  using  the  ADT  plug
-­‐
in,  you  can  put  the  AIDL  file  into  your  project  and  use  
the  Ant  tool  to  build  your  project  so  that  the  
IMarketBillingService.java
 
file  gets  generated.
 
To  add  the  
IMarketBillingService.aidl
 
file  to  your  project,  do  the  following:
 


Create  the  following  directory  in  your  application

s  
/src
 
directory:
com/android/vending/billing/
 


Copy the
IMarketBillingService.aidl

file into the
sample/src/com/android/vending/billing/

directory.



Build  your  applic
ation.
 
You  should  now  find  a  generated  interface  file  named  
IMarketBillingService.java
 
in  the  
gen
 
folder  of  your  project.
 
Updating  Your  Application

s  Manifest
 
In
-­‐
app  billing  relies  on  the  Android  Market  application,  which  handles  all  communication  between  
your  application  and  the  Android  Market  server.  To  use  the  Android  Market  application,  your  
application  must  request  the  proper  permission.  You  can  do  this  by  adding  the  
com.android.vending.BILLING
 
permission  to  your  AndroidManifest.xml  file.  If  your  appli
cation  
does  not  declare  the  in
-­‐
app  billing  permission,  but  attempts  to  send  billing  requests,  Android  Market  
will  refuse  the  requests  and  respond  with  a  
RESULT_DEVELOPER_ERROR
 
response  code.
 
In  addition  to  the  billing  permission,  you  need  to  declare  the  
BroadcastReceiver
 
that  you  will  use  
to  receive  asynchronous  response  messages  (broadcast  intents)  from  Android  Market,  and  you  need  
to  declare  the  
Service
 
that  you  will  use  to  bind  with  the  
IMarketBillingService
 
and  send  
messages  to  Android  Market.  You  must  also  declare  
intent  filters
 
for  the  
BroadcastReceiver
 
so  
that  the  Android  system  kn
ows  how  to  handle  the  broadcast  intents  that  are  sent  from  the  Android  
Market  application.
 
For  example,  here  is  how  the  in
-­‐
app  billing  sample  application  declares  the  billing  permission,  the  
BroadcastReceiver
,  the  
Service
,  and  the  intent  filters.  In  the  sample  application,  
BillingReceiver
 
is  the  
BroadcastReceiver
 
that  handles  broadcast  intents  from  the  Android  
Market  application  and  
BillingService
 
is  the  
Service
 
that
 
sends  requests  to  the  Android  
Market  application.
 
<?
xml  version
=

1.0

 
encoding
=

utf
-­‐
8

?>
 
<manifest
xmlns:android
=

http://schemas.android.com/apk/res/android

 
package
=

com.example.dungeons

 
android:versionCode
=

1

 
android:versionName
=

1.0

>
 

<uses
-­‐
permission
android:name
=

com.android.vending.BILLING

/>
 
<application
android:icon
=

@drawable/icon

android:label
=

@string/app_name

>
 
<activity
android:name
=

.Dungeons

android:label
=

@string/app_name

>
 
<
intent
-­‐
filter>
 
<action
android:name
=

android.intent.action.MAIN

/>
 
<category
android:name
=

android.intent.category.LAUNCHER

/>
 
</intent
-­‐
filter>
 
</activity>
 
<service
android:name
=

BillingService

/>
 
<receiver
android:name
=

BillingReceiver

>
 
<intent
-­‐
filter>
 
<
action
android:name
=

com.android.vending.billing.IN_APP_NOTIFY

/>
 
<action
android:name
=

com.android.vending.billing.RESPONSE_CODE

/>
 
<action
android:name
=

com.android.vending.billing.PURCHASE_STATE_CHANGED

/>
 
</intent
-­‐
filter>
 
</receiver>
 
</application>
 
<
/manifest>
 
Creating  a  Local  Service
 
Your  application  must  have  a  local  
Service
 
to  facilitate  messaging  between  your  application  and  
Android  Market.  At  a  minimum,  this  service  m
ust  do  the  following:
 
10.

Bind to the
MarketBillingService
.

11.

Send  billing  requests  (as  IPC  method  calls)  to  the  Android  Market  application.  The  five  types  of  
billing  requests  include:
 

CHECK_BILLING_SUPPORTED

requests


REQUEST_PURCHASE

requests


GET_PURCHASE_INFORMATION

requests


CONFIRM_NOTIFICATIONS

requests


RESTORE_TRANSACTIONS

requests

12.

Handle  the  synchronous  response  messages  that  are  returned  with  each  billing  request.
 
Binding  to  the  MarketBillingService
 
Binding  to  the  
MarketBillingService
 
is  
relatively  easy  if  you

ve  already  added  the  
IMarketBillingService.aidl
 
file  to  your  project.  The  following  code  sample  shows  how  to  
use  the  
bindService()
 
method  to  bind  a  service  to  the  
MarketBillingService
.  You  could  put  
this  co
de  in  your  service

s  
onCreate()
 
method.
 
try
{
 
boolean
 
bindResult  
=
 
mContext
.
bindService
(
 
new
Intent
(

com.android.vending.billing.MarketBillingSe
rvice.BIND

),
this
,
 
Context
.
BIND_AUTO_CREATE
);
 
if
(
bindResult
){
 
Log
.
i
(
TAG
,

Service  bind  successful.

);
 
}
else
{
 
Log
.
e
(
TAG
,

Could  not  bind  to  the  MarketBillingService.

);
 


}

}
catch
(
SecurityException  e
){
 
Log
.
e
(
TAG
,

Security  exception:  

+
 
e
);
 
}

After  you  bind  to
 
the
 
service,  you  need  to  create  a  reference  to  the  
IMarketBillingService
 
interface  so  you  can  make  billing  requests  via  IPC  method  calls.  The  following  code  shows  you  how  to  
do  this  using  the  
onServiceConnected()
 
callback  method.
 
/**



The  Android  system  calls  this  when  we  are  connected  to  the  MarketBillingService.
 


*/

publicvoid
 
onServiceConnected
(
ComponentName
 
name
,
IBinder
 
service
){
 
Log
.
i
(
TAG
,

MarketBillingService  connected.

);
 
mService  
=
IMarketBillingService
.
Stub
.
asInterface
(
service
);
 


}

You  can  now  use  the  
mService
 
reference  to  invoke  the  
sendBillingRequest()
 
method.
 
For  a  complete  implementation  of  a  service  that  binds  to  the  
MarketBillingService
,  see  the  
BillingService
 
class  in  the  sample  application.
 
Sending  billing  requests  to  the  MarketBillingService
 
Now  that  your  
Service
 
has  a  reference  to  the  
IMarketBillingService
 
interface,  you  can  use  
that  reference  to  send  billing  requests  (via  IPC  method  calls)  to  the  
MarketBillingService
.  The  
MarketBillingService
 
IPC  interface  exposes  a  single  pu
blic  method  
(
sendBillingRequest()
),  which  takes  a  single  
Bundle
 
parameter.  The  Bundle  that  you  deliver  
with  this  method  specifies  the  type  of  request  you  want  to  perform,  using  v
arious  key
-­‐
value  pairs.  For  
instance,  one  key  indicates  the  type  of  request  you  are  making,  another  indicates  the  item  being  
purchased,  and  another  identifies  your  application.  The  
sendBillingRequest()
 
method  
immediately  returns  a  Bundle  containing  an  init
ial  response  code.  However,  this  is  not  the  complete  
purchase  response;  the  complete  response  is  delivered  with  an  asynchronous  broadcast  intent.  For  
more  information  about  the  various  Bundle  keys  that  are  supported  by  the  
MarketBillingService
,  see  
In
-­‐
app  Billing  Service  Interface
.
 
You  can  use  the  
sendBillingRequest()
 
method  to  send  five  types  of  billing  requests.  The  five  
request  types  are  specified  using  the  
BILLING_REQUEST
 
Bundle  key.  This  Bundle  key  can  have  the  
following  five  values:
 


CHECK_BILLING_SUPPORTED

verifies  that  the  Android  Market  application  supports  in
-­‐
app  
billing.
 


REQUEST_PURCHASE

sends  a  purchase  request  for  an  in
-­‐
app  item.
 


GET_PURCHASE_INFORMATION

retrieves  transaction  information  for  a  purchase  or  refund.
 


CONFIRM_NOTIFICATIONS

acknowledges  that  you  received  the  transaction  information  
for  a  purchase  
or  refund.
 


RESTORE_TRANSACTIONS

retrieves  a  user

s  transaction  history  for  
managed  purchases
.
 
To  make  any  of  these  billing  requests,  you  first  n
eed  to  build  an  initial  
Bundle
 
that  contains  the  three  
keys  that  are  required  for  all  requests:  
BILLING_REQUEST
,  
API_VERSION
,  and  
PACKAGE_NAME
.  
The  following  code  sample  shows  yo
u  how  to  create  a  helper  method  named  
makeRequestBundle()
 
that  does  this.
 
protected
Bundle
 
makeRequestBundle
(
String
 
method
){
 
Bundle  request  
=
new
Bundle
();
 
request
.
putString
(
BILLING_REQUEST
,
 
method
);
 
request
.
putInt
(
API_VERSION
,
1
);
 
request
.
putString
(
PACKAGE_NAME
,
 
getPackageName
());
 
return
 
request
;
 
To  use  this  helper  method,  you  pass  in  a  
String
 
that  corresponds  to  one  of  the  five  types  of  billing  
requests.  The  method  returns  a  Bundle  that  has  the  three  required  keys  defined.  The  following  
sections  show  you  how  to  use  this  helper  method  when  you  send  a  billing  request.
 
Important
:  You  must  make  
all  in
-­‐
app  billing  requests  from  your  application

s  main  thread.
 
Verifying  that  in
-­‐
app  billing  is  supported  (CHECK_BILLING_SUPPPORTED)
 
The  following  code  sample  shows  how  to  verify  whether  the  Android  Market  application  supports  in
-­‐
app  billing.  In  the  samp
le,  
mService
 
is  an  instance  of  the  
MarketBillingService
 
interface.
 
/**



Request  type  is  CHECK_BILLING_SUPPORTED
 
*/

Bundle
 
request  
=
 
makeRequestBundle
(

CHECK_BILLING_SUPPORTED

);
 
Bundle
 
response  
=
 
mService
.
sendBillingRequest
(
request
);
 
//  Do  something  with  
this  response.
 
}

The  
makeRequestBundle()
 
method  constructs  an  initial  Bundle,  which  contains  the  three  keys  
that  are  required  for  all  requests:  
BILLING_REQUEST
,  
API_VERSION
,  and  
PACKAGE_NAME
.  The  
request  returns  a  synchronous  
Bundle
 
response,  which  contains  only  a  single  key:  
RESPONSE_CODE
.  The  
RESPONSE_CODE
 
key  can  have  the  following  values:
 


RESULT_OK

in
-­‐
app  billing  is  supported.
 


RESULT_BILLING_UNAVAIL
ABLE

in
-­‐
app  billing  is  not  available  because  the  API  version  
you  specified  is  not  recognized  or  the  user  is  not  eligible  to  make  in
-­‐
app  purchases  (for  
example,  the  user  resides  in  a  country  that  prohibits  in
-­‐
app  purchases).
 


RESULT_ERROR

there  was  an  error  
connecting  with  the  Android  Market  application.
 


RESULT_DEVELOPER_ERROR

the  application  is  trying  to  make  an  in
-­‐
app  billing  request  but  
the  application  has  not  declared  the  
com.android.vending.BILLING
permission  in  its  
manifest.  Can  also  indicate  that  an  app
lication  is  not  properly  signed,  or  that  you  sent  a  
malformed  request.
 
The  
CHECK_BILLING_SUPPORTED
 
request  does  not  trigger  any  asynchronous  responses  
(broadcast  intents).
 
We  recommend  that  you  invoke  the  
CHECK_BILLING_SUPPORTED
 
request  within  a  
RemoteExce
ption
 
block.  When  your  code  throws  a  
RemoteException
 
it  indicates  that  the  
remote  method  call  failed,  which  means  that  the  Android  Market  application  is  out  of  date  and  needs  
to  be  updated.  In  this  case,  you  can  provide  users  with  an  error  message  that  con
tains  a  link  to  the  
Updating  Android  Market
 
Help  topic.
 
The  sample  application  demonstrates  how  you  can  handle  this  error  condition  (see  
DIALOG_CANNOT_CONNECT_ID
 
in  
Dungeons.java
).
 
Making  a  purchase  request  (REQUEST_PURCHASE)
 
To  make  a  purchase  request  you  must  do  the  following:
 


Send  the  
REQUEST_PURCHASE
 
request.
 


Launch  the  
PendingIntent
 
that  is  
returned  from  the  Android  Market  application.
 


Handle  the  broadcast  intents  that  are  sent  by  the  Android  Market  application.
 
Making  the  request
 
You  must  specify  four  keys  in  the  request  
Bundle
.  The  following  code  sample  shows  how  to  set  
these  keys  and  make  a  purchase  request  for  a  single  in
-­‐
app  item.  In  the  sample,  
mProductId
 
is  the  
Android  Market  product  ID  of  an
 
in
-­‐
app  item  (which  is  listed  in  the  application

s  
product  list
),  and  
mService
 
is  an  instance  of  the  
MarketBillingService
 
interface.
 
/**



Request  ty
pe  is  REQUEST_PURCHASE
 
*/

Bundle
 
request  
=
 
makeRequestBundle
(

REQUEST_PURCHASE

);
 
request
.
putString
(
ITEM_ID
,
 
mProductId
);
 
//  Note  that  the  developer  payload  is  optional.
 
if
(
mDeveloperPayload  
!=
null
){
 
request
.
putString
(
DEVELOPER_PAYLOAD
,
 
mDeveloperPayload
);
 
Bundle
 
response  
=
 
mService
.
sendBillingRequest
(
request
);
 
//  Do  something  with  this  response.
 


}

The  
makeRequestBundle()
 
method  constructs  an  initial  Bundle,  which  contains  the  three  keys  
that  are  required  for  all  requests:  
BILLING_REQUEST
,  
API_VERSION
,  and  
PACKAGE_NAME
.  The  
ITEM_ID
 
key  is  then  added  to  the  Bundle  prior  to  invoking  the  
sendBillingRequest()
 
method.
 
The  request  returns  a  synchronous  
Bundle
 
response,  which  contai
ns  three  keys:  
RESPONSE_CODE
,  
PURCHASE_INTENT
,  and  
REQUEST_ID
.  The  
RESPONSE_CODE
 
key  provides  you  with  the  status  of  
the  request  and  the  
REQUEST_ID
 
key  provides  you  with  a  unique  request  identifier  for  the  request.  
The  
PURCHASE_INTENT
 
key  provides  you  with
 
a  
PendingIntent
,  which  you  can  use  to  launch  the  
checkout  UI.
 
Using  the  pending  intent
 
How  you  use  the  pending  intent  depends  on  which  version  of  Android  a  device  is  run
ning.  On  Android  
1.6,  you  must  use  the  pending  intent  to  launch  the  checkout  UI  in  its  own  separate  task  instead  of  your  
application

s  activity  stack.  On  Android  2.0  and  higher,  you  can  use  the  pending  intent  to  launch  the  
checkout  UI  on  your  application

s
 
activity  stack.  The  following  code  shows  you  how  to  do  this.  You  can  
find  this  code  in  the  
PurchaseObserver.java
 
file  in  the  sample  application.
 
void
 
startBuyPageActivity
(
PendingIntent
 
pendingIntent
,
Intent
 
intent
){
 
if
(
mStartIntentSender  
!=
null
){
 
//  This  
is  on  Android  2.0  and  beyond.  
 
The  in
-­‐
app  checkout  page  activity
 
//  will  be  on  the  activity  stack  of  the  application.
 
try
{
 
//  This  implements  the  method  call:
 
//  mActivity.startIntentSender(pendingIntent.getIntentSender(),
 
//  
 
 
 
 
intent,  0,  0,  0);
 
mStartIntentSenderArgs
[
0
]=
 
pendingIntent
.
getIntentSender
();
 
mStartIntentSenderArgs
[
1
]=
 
intent
;
 
mStartIntentSenderArgs
[
2
]=
Integer
.
valueOf
(
0
);
 
mStartIntentSenderArgs
[
3
]=
Integer
.
valueOf
(
0
);
 
mStartIntentSenderArgs
[
4
]=
Integer
.
valueOf
(
0
);
 
mStartIntentSender
.
invoke
(
mActivity
,
 
mStartIntentSenderArgs
);
 
}
catch
(
Exception  e
){
 
Log
.
e
(
TAG
,

error  starting  activity

,
 
e
);
 






}

}
else
{
 
//  This  is  on  Android  1.6.  The  in
-­‐
app  checkout  page  activity  will  be  on  its
 
//  own  separate  activity  stack  instead  of  on  the  activity  
stack  of
 
//  the  application.
 
try
{
 
pendingIntent
.
send
(
mActivity
,
0
/*  code  */
,
 
intent
);
 
}
catch
(
CanceledException  e
){
 
Log
.
e
(
TAG
,

error  starting  activity

,
 
e
);
 






}



}

}

Important:
 
You  must  launch  the  pending  intent  from  an  activity  context  and  not  an  application  
context.  Also,  you  cannot  use  the  
singleTop
 
launch  mode
 
to  launch  the  pe
nding  intent.  If  you  do  
either  of  these,  the  Android  system  will  not  attach  the  pending  intent  to  your  application  process.  
Instead,  it  will  bring  Android  Market  to  the  foreground,  disrupting  your  application.
 
Handling  broadcast  intents
 
A  
REQUEST_PURCHASE
 
request  also  triggers  two  asynchronous  responses  (broadcast  intents).  First,  
the  Android  Market  application  sends  a  
RESPONSE_CODE
 
broadcast  intent,  which  provides  error  
information  about  the  request.  If  the  request  does  not  generate  an  error,  the  
RESPONSE
_CODE
 
broadcast  intent  returns  
RESULT_OK
,  which  indicates  that  the  request  was  successfully  sent.  (To  be  
clear,  a  
RESULT_OK
 
response  does  not  indicate  that  the  requested  purchase  was  successful;  it  
indicates  that  the  request  was  sent  successfully  to  Androi
d  Market.)
 
Next,  when  the  requested  transaction  changes  state  (for  example,  the  purchase  is  successfully  
charged  to  a  credit  card  or  the  user  cancels  the  purchase),  the  Android  Market  application  sends  an  
IN_APP_NOTIFY
 
broadcast  intent.  This  message  contai
ns  a  notification  ID,  which  you  can  use  to  
retrieve  the  transaction  details  for  the  
REQUEST_PURCHASE
 
request.
 
Note:
 
The  Android  Market  application  also  sends  an  
IN_APP_NOTIFY
 
for  refunds.  For  more  
information,  see  
Handling  IN_APP_NOTIFY  messages
.
 
Because  the  purchase  process  is  not  instantaneous  and  can  take  several  seconds  (or  more),  you  must  
assume  that
 
a  purchase  request  is  pending  from  the  time  you  receive  a  
RESULT_OK
 
message  until  
you  receive  an  
IN_APP_NOTIFY
 
message  for  the  transaction.  While  the  transaction  is  pending,  the  
Android  Market  checkout  UI  displays  an  

Authorizing  purchase...

 
notification
;  however,  this  
notification  is  dismissed  after  60  seconds  and  you  should  not  rely  on  this  notification  as  your  primary  
means  of  conveying  transaction  status  to  users.  Instead,  we  recommend  that  you  do  the  following:
 


Add  an  
Activity
 
to  your  application  that  shows  users  the  status  of  pending  and  completed  
in
-­‐
app  purchases.
 


Use  a  
status  bar  
notification
 
to  keep  users  informed  about  the  progress  of  a  purchase.
 
To  use  these  two  UI  elements,  you  could  invoke  a  status  bar  notification  with  a  ticker
-­‐
text  message  
that  says  

Purchase  pending

 
when  your  application  receives  a  
RESULT_OK
 
message.  Then,
 
when  
your  application  receives  an  
IN_APP_NOTIFY
 
message,  you  could  update  the  notification  with  a  new  
message  that  says  

Purchase  succeeded

 
or  

Purchase  failed.

 
When  a  user  touches  the  expanded  
status  bar  notification,  you  could  launch  the  activity  that
 
shows  the  status  of  pending  and  completed  
in
-­‐
app  purchases.
 
If  you  use  some  other  UI  technique  to  inform  users  about  the  state  of  a  pending  transaction,  be  sure  
that  your  pending  status  UI  does  not  block  your  application.  For  example,  you  should  avoid  usi
ng  a  
hovering  progress  wheel  to  convey  the  status  of  a  pending  transaction  because  a  pending  transaction  
could  last  a  long  time,  particularly  if  a  device  loses  network  connectivity  and  cannot  receive  
transaction  updates  from  Android  Market.
 
Important:
 
If  a
 
user  purchases  a  managed  item,  you  must  prevent  the  user  from  purchasing  the  item  
again  while  the  original  transaction  is  pending.  If  a  user  attempts  to  purchase  a  managed  item  twice,  
and  the  first  transaction  is  still  pending,  Android  Market  will  display
 
an  error  to  the  user;  however,  
Android  Market  will  not  send  an  error  to  your  application  notifying  you  that  the  second  purchase  
request  was  canceled.  This  might  cause  your  application  to  get  stuck  in  a  pending  state  while  it  waits  
for  an  
IN_APP_NOTIFY
 
mes
sage  for  the  second  purchase  request.
 
Retrieving  transaction  information  for  a  purchase  or  refund  (GET_PURCHASE_INFORMATION)
 
You  retrieve  transaction  information  in  response  to  an  
IN_APP_NOTIFY
 
broadcast  intent.  The  
IN_APP_NOTIFY
 
message  contains  a  notification  ID,  which  you  can  use  to  retrieve  transaction  
information.
 
To  retrieve  transaction  information  for  a  purchase  or  refund  you  must  specify  five  keys  in  the  request  
Bundle
.  The  following  code  sample  shows  how  to  set  these  keys  and  make  the  request.  In  the  
sample,  
mService
 
is  an  instance  of  the  
MarketBillingService
 
interface.
 
/**



Request  type  is  GET_PURCHASE_INFORMATION
 
*/

Bundle
 
request  
=
 
makeRequestBundle
(

GET_PURCHASE_INFORMATION

);
 
request
.
putLong
(
REQUEST_NONCE
,
 
mNonce
);
 
request
.
putStringArray
(
NOTIFY_IDS
,
 
mNotifyIds
);
 
Bundle
 
response  
=
 
mService
.
sendBillingRequest
(
request
);
 
//  Do  something  with  this  response.
 
}

The  
makeRequestBundle()
 
method  constructs  an  initial  Bundle,  which  contains  the  three  keys  
that  are  required  for  all  requests:  
BILLING_REQUEST
,  
API_VERSION
,  and  
PACKAGE_NAME
.  The  
additional  keys  are  then  added  to  the  bundle  prior  to  invoking  the  
sendBillingRequest()
 
method.  The  
REQUEST_NONCE
 
key  contains  a  cryptographically  secure  nonce  (number  used  once)  
that  you  must  generate.  The  Android  Market  application  returns  this  nonce  with  the  
PURCHASE_STATE_CHANGED
 
broadcast  intent  so  you  can  verify  the  integrity  of  the  transaction  
inf
ormation.  The  
NOTIFY_IDS
 
key  contains  an  array  of  notification  IDs,  which  you  received  in  the  
IN_APP_NOTIFY
 
broadcast  intent.
 
The  request  returns  a  synchronous  
Bundle
 
response,  w
hich  contains  two  keys:  
RESPONSE_CODE
 
and  
REQUEST_ID
.  The  
RESPONSE_CODE
 
key  provides  you  with  the  status  of  the  request  and  the  
REQUEST_ID
 
key  provides  you  with  a  unique  request  identifier  for  the  request.
 
A  
GET_PURCHASE_INFORMATION
 
request  also  triggers  t
wo  asynchronous  responses  (broadcast  
intents).  First,  the  Android  Market  application  sends  a  
RESPONSE_CODE
 
broadcast  intent,  which  
provides  status  and  error  information  about  the  request.  Next,  if  the  request  was  successful,  the  
Android  Market  application  
sends  a  
PURCHASE_STATE_CHANGED
 
broadcast  intent.  This  message  
contains  detailed  transaction  information.  The  transaction  information  is  contained  in  a  signed  JSON  
string  (unencrypted).  The  message  includes  the  signature  so  you  can  verify  the  integrity  of  t
he  signed  
string.
 
Acknowledging  transaction  information  (CONFIRM_NOTIFICATIONS)
 
To  acknowledge  that  you  received  transaction  information  you  send  a  
CONFIRM_NOTIFICATIONS
 
request.  You  must  specify  four  keys  in  the  request  
Bundle
.  The  following  code  sample  shows  how  to  
set  these  keys  and  make  the  request.  In  the  sample,  
mService
 
is  an  instance  of  the  
MarketBillingService
 
interface.
 

/**



Request  type  
is  CONFIRM_NOTIFICATIONS
 
*/

Bundle
 
request  
=
 
makeRequestBundle
(

CONFIRM_NOTIFICATIONS

);
 
request
.
putStringArray
(
NOTIFY_IDS
,
 
mNotifyIds
);
 
Bundle
 
response  
=
 
mService
.
sendBillingRequest
(
request
);
 
//  Do  something  with  this  response.
 
}

The  
makeRequestBundle()
 
method  constructs  an  initial  Bundle,  which  contains  the  three  keys  
that  are  required  for  all  requests:  
BILLING_REQUEST
,  
API_VERSION
,  and  
PACKAGE_NAME
.  The  
additional  
NOTIFY_IDS
 
key  is  then  added  to  the  bundle  prior  to  invoking  the  
sendBillingRequest()
 
met
hod.  The  
NOTIFY_IDS
 
key  contains  an  array  of  notification  IDs,  
which  you  received  in  an  
IN_APP_NOTIFY
 
broadcast  intent  and  also  used  in  a  
GET_PURCHASE_INFORMATION
 
request.
 
The  request  returns  a  synchronous  
Bundle
 
response,  which  contains  two  keys:  
RESPONSE_CODE
 
and  
REQUEST_ID
.  The  
RESPONSE_CODE
 
key  provides  you  with  the  status  of  the  request  and  the  
REQUEST_ID
 
key  provides  you  with  a  unique  request  identifier  for  the  request.
 
A  
CONFIRM_NOTIFICATIONS
 
request  triggers  a  single  asynchronous  response

a  
RESPONSE_CODE
 
broadcast  intent.  This  broadcast  intent  provides  status  and  error  information  about  
the  request.
 
You  must  send  a  confirmation  when  you  receive  transaction  information  fro
m  Android  Market.  If  you  
don

t  send  a  confirmation  message,  Android  Market  will  continue  sending  
IN_APP_NOTIFY
 
messages  for  the  transactions  you  have  not  confirmed.  Also,  your  application  must  be  able  to  handle  
IN_APP_NOTIFY
 
messages  that  contain  multiple  
orders.
 
In  addition,  as  a  best  practice,  you  should  not  send  a  
CONFIRM_NOTIFICATIONS
 
request  for  a  
purchased  item  until  you  have  delivered  the  item  to  the  user.  This  way,  if  your  application  crashes  or  
something  else  prevents  your  application  from  deliveri
ng  the  product,  your  application  will  still  receive  
an  
IN_APP_NOTIFY
 
broadcast  intent  from  Android  Market  indicating  that  you  need  to  deliver  the  
product.
 

Restoring  transaction  information  (RESTORE_TRANSACTIONS)
 
To  restore  a  user

s  transaction  information
,  you  send  a  
RESTORE_TRANSACTIONS
 
request.  You  must  
specify  four  keys  in  the  request  
Bundle
.  The  following  code  sample  shows  how  to  set  these  keys  and  
make  the  request.  In  the  sa
mple,  
mService
 
is  an  instance  of  the  
MarketBillingService
 
interface.
 
/**



Request  type  is  RESTORE_TRANSACTIONS
 
*/

Bundle
 
request  
=
 
makeRequestBundle
(

RESTORE_TRANSACTIONS

);
 
request
.
putLong
(
REQUEST_NONCE
,
 
mNonce
);
 
Bundle
 
response  
=
 
mService
.
sendBillingRequest
(
request
);
 
//  Do  something  with  this  response.
 
}

The  
makeRequestBundle()
 
method  constructs  an  initial  Bundle,  which  contains  the  three  keys  
that  are  required  for  all  requests:  
BILLING_REQUEST
,  
API_VERSION
,  and  
PACKAGE_NAME
.  The  
additional  
REQUEST_NONCE
 
key  is  then  added  to  the  bundle  prior  to  invoking  the  
sendBillingRequest()
 
method.  The  
REQUEST_NONCE
 
key  contains  a  cryptographically  secure  
nonce  (number  used  once)  that  you  must  generate.  The  Android  Market  application  retu
rns  this  
nonce  with  the  transactions  information  contained  in  the  
PURCHASE_STATE_CHANGED
 
broadcast  
intent  so  you  can  verify  the  integrity  of  the  transaction  information.
 
The  request  returns  a  synchronous  
Bundle
 
response,  which  contains  two  keys:  
RESPONSE_CODE
 
and  
REQUEST_ID
.  The  
RESPONSE_CODE
 
key  provides  you  with  the  status  of  the  request  and  the  
REQUEST_ID
 
key  provides  you  with  a  unique  request  identifier  for  the  request.
 
A  
REST
ORE_TRANSACTIONS
 
request  also  triggers  two  asynchronous  responses  (broadcast  intents).  
First,  the  Android  Market  application  sends  a  
RESPONSE_CODE
 
broadcast  intent,  which  provides  
status  and  error  information  about  the  request.  Next,  if  the  request  was  suc
cessful,  the  Android  
Market  application  sends  a  
PURCHASE_STATE_CHANGED
 
broadcast  intent.  This  message  contains  
the  detailed  transaction  information.  The  transaction  information  is  contained  in  a  signed  JSON  string  
(unencrypted).  The  message  includes  the  si
gnature  so  you  can  verify  the  integrity  of  the  signed  string.
 
Note:
 
You  should  use  the  
RESTORE_TRANSACTIONS
 
request  type  only  when  your  application  is  
installed  for  the  first  time  on  a  device  or  when  your  application  has  been  removed  from  a  device  and  
rein
stalled.
 
Other  service  tasks
 
You  may  also  want  your  
Service
 
to  receive  intent  messages  from  your  
BroadcastReceiver
.  You  
can  use  these  intent  messages  to  convey  the  information  that  was  sent  asynchronously  from  the  
Android  Market  application  to  your  
BroadcastReceiver
.  To  see  an  example  of  how  you  can  send  
and  receive  these  intent  messages,  see  the  
BillingReceiver.java
 
and  
BillingService.java
 
files  in  the  sample  applicati
on.  You  can  use  these  samples  as  a  basis  for  
your  own  implementation.  However,  if  you  use  any  of  the  code  from  the  sample  application,  be  sure  
you  follow  the  guidelines  in  
Security  and  Design
.
 
Creating  a  BroadcastReceiver
 
The  Android  Market  application  uses  broadcast  intents  to  send  asynchronous  billing  responses  to  your  
application.  To  receive  these  intent  messages,  you  need  to  create  a  
BroadcastReceiver
 
that  can  
handle  the  following  intents:
 


com.android.vending.billing.RESPONSE_CODEThis  broadcast  intent  contains  an  Android  
Market  response  code,  and  is  sent  after  you  make  
an  in
-­‐
app  billing  request.  For  more  
information  about  the  response  codes  that  are  sent  with  this  response,  see  
Android  Market  
Response  Codes  for  In
-­‐
app  Billing
.
 


com.android.vending.billing.IN_APP_NOTIFYThis  response  indicates  that  a  purchase  has  
changed  state,  which  means  a  purchase  succeeded,  was  canceled,  or  was  refunded.  For  more  
information  about  notification  messages,  see  
In
-­‐
app  Billing  Broadcast  Intents
 


com.android.vending.billing.PURCHASE_STATE_CHANGEDThis  broadcast  intent  contains  
detailed  information  about  one  or  more  transactions.  For
 
more  information  about  purchase  
state  messages,  see  
In
-­‐
app  Billing  Broadcast  Intents
 
Each  of  these  broadcast  intents  provide  intent  extras,  which
 
your  
BroadcastReceiver
 
must  
handle.  The  intent  extras  are  listed  in  the  following  table  (see  table  1).
 
Table  1.
 
Description  of  broadcast  intent  extras  that  are  s
ent  in  response  to  billing  requests.
 
Intent

Extra

Description

com.android.vending.billing
.RESPONSE_CODE

request_id

A
long

representing a
request ID. A request ID
identifies a specific billing
request and is returned by
Android Market at the time a
request is made.

com.android.vending.billing
.RESPONSE_CODE

response_code

An
int

representing the
actual Android Market
server re
sponse code.

com.android.vending.billing
.IN_APP_NOTIFY

notification_id

A
String

representing the
notification ID for a given
purchase state change.
Android Market notifies you
when there is a purchase
state change and the
notification includes a
unique no
tification ID. To
get the details of the
purchase state change, you
send the notification ID with
the
GET_PURCHASE_INFORMAT
ION

request.


com.android.vending.billing
.PURCHASE_STATE_CHANGED

inapp_signed_da
ta

A
String

representing the
signed JSON string. The

JSON string contains
information about the billing
transaction, such as order
number, amount, and the
item that was purchased or
refunded.

com.android.vending.billing
.PURCHASE_STATE_CHANGED

inapp_signature

A
String

representing the
signature of the JSON
string.

 
The  following  code  sample  shows  how  to  handle  these  broadcast  intents  and  intent  extras  within  a  
BroadcastReceiv
er
.  The  BroadcastReceiver  in  this  case  is  named  
BillingReceiver
,  just  as  it  
is  in  the  sample  application.
 
publicclass
BillingReceiver
extends
BroadcastReceiver
{
 
privatestaticfinal
String
 
TAG  
=

BillingReceiver

;
 
//  Intent  actions  that  we  receive  in  the  
BillingReceiver  from  Android  Market.
 
//  These  are  defined  by  Android  Market  and  cannot  be  changed.
 
//  The  sample  application  defines  these  in  the  Consts.java  file.
 
publicstaticfinal
String
 
ACTION_NOTIFY  
=

com.android.vending.billing.IN_APP_NOTIFY

;
 
publicst
aticfinal
String
 
ACTION_RESPONSE_CODE  
=

com.android.vending.billing.RESPONSE_CODE

;
 
publicstaticfinal
String
 
ACTION_PURCHASE_STATE_CHANGED  
=
 

com.android.vending.billing.PURCHASE_STATE_CHANGED

;
 
//  The  intent  extras  that  are  passed  in  an  intent  from  Android  
Market.
 
//  These  are  defined  by  Android  Market  and  cannot  be  changed.
 
//  The  sample  application  defines  these  in  the  Consts.java  file.
 
publicstaticfinal
String
 
NOTIFICATION_ID  
=

notification_id

;
 
publicstaticfinal
String
 
INAPP_SIGNED_DATA  
=

inapp_signed_data

;
 
publicstaticfinal
String
 
INAPP_SIGNATURE  
=

inapp_signature

;
 
publicstaticfinal
String
 
INAPP_REQUEST_ID  
=

request_id

;
 
publicstaticfinal
String
 
INAPP_RESPONSE_CODE  
=

response_code

;
 

@Override
 
publicvoid
 
onReceive
(
Context
 
context
,
Intent
 
intent
){
 
String
 
action  
=
 
intent
.
getAction
();
 
if
(
ACTION_PURCHASE_STATE_CHANGED
.
equals
(
action
)){
 
String
 
signedData  
=
 
intent
.
getStringExtra
(
INAPP_SIGNED_DATA
);
 
String
 
signature  
=
 
intent
.
getStringExtra
(
INAPP_SIGNATURE
);
 
//  Do  something  with  the  signedData  and  the  signature.
 
}
elseif
(
ACTION_NOTIFY
.
equals
(
action
)){
 
String
 
notifyId  
=
 
intent
.
getStringExtra
(
NOTIFICATION_ID
);
 
//  Do  something  with  the  notifyId.
 
}
elseif
(
ACTION_RESPONSE_CODE
.
equals
(
action
)){
 
long
 
requestId  
=
 
intent
.
getLongExtra
(
INAPP_REQUEST_ID
,
-­‐
1
);
 
int
 
responseCodeIndex  
=
 
intent
.
getIntExtra
(
INAPP_RESPONSE_CODE
,
 
ResponseCode
.
RESULT_ERROR
.
ordinal
());
 
//  Do  something  with  the  requestId  and  the  responseCodeIndex.
 
}
else
{
 
Log
.
w
(
TAG
,

unexpected  action:  

+
 
action
);
 




}



}

//  Perform  other  processing  here,  
such  as  forwarding  intent  messages  to  your  local  service.
 
}

 
In  addition  to  receiving  broadcast  intents  from  the  Android  Market  application,  your  
BroadcastReceive
r
 
must  handle  the  information  it  received  in  the  broadcast  intents.  Usually,  
your  
BroadcastReceiver
 
does  this  by  sending  the  information  to  a  local  service  (discu
ssed  in  the  
next  section).  The  
BillingReceiver.java
 
file  in  the  sample  application  shows  you  how  to  do  
this.  You  can  use  this  sample  as  a  basis  for  your  own  
Broad
castReceiver
.  However,  if  you  use  any  
of  the  code  from  the  sample  application,  be  sure  you  follow  the  guidelines  that  are  discussed  in  
Security  and  Design
 
.
 
Verifying  Signatures  and  Nonces
 
Android  Market

s  in
-­‐
app  billing  service  uses  two  mechanisms  to  help  verify  the  integrity  of  the  
transaction  information  you  receive  from  Android  Market:  nonces  and  signatures.  A  nonce  (number  
used  once)  is  a  cryptographicall
y  secure  number  that  your  application  generates  and  sends  with  every  
GET_PURCHASE_INFORMATION
 
and  
RESTORE_TRANSACTIONS
 
request.  The  nonce  is  returned  
with  the  
PURCHASE_STATE_CHANGED
 
broadcast  intent,  enabling  you  to  verify  that  any  given  
PURCHASE_STATE_CHA
NGED
 
response  corresponds  to  an  actual  request  that  you  made.  Every  
PURCHASE_STATE_CHANGED
 
broadcast  intent  also  includes  a  signed  JSON  string  and  a  signature,  
which  you  can  use  to  verify  the  integrity  of  the  response.
 
Your  application  must  provide  a  way  t
o  generate,  manage,  and  verify  nonces.  The  following  sample  
code  shows  some  simple  methods  you  can  use  to  do  this.
 
privatestaticfinal
SecureRandom  RANDOM  
=
new
SecureRandom
();
 
privatestatic
HashSet
<
Long
>
 
sKnownNonces  
=
new
HashSet
<
Long
>();
 
publicstaticlong  gener
ateNonce
(){
 
long
 
nonce  
=
 
RANDOM
.
nextLong
();
 
sKnownNonces
.
add
(
nonce
);
 
return
 
nonce
;
 


}


publicstaticvoid  removeNonce
(
long  nonce
){
 
sKnownNonces
.
remove
(
nonce
);
 


}


publicstaticboolean  isNonceKnown
(
long  nonce
){
 
return
 
sKnownNonces
.
contains
(
nonce
);
 


}

Your  application  must  also  provide  a  way  to  verify  the  signatures  that  accompany  every  
PURCHASE_STATE_CHANGED
 
broadcast  intent.  The  
Security.java
 
file  in  the  sample  application  
shows  you  how  to  do  this.  If  you  use  this  file  as  a  basis  for  your  own  security
 
implementation,  be  sure  
to  follow  the  guidelines  in  
Security  and  Design
 
and  obfuscate  your  code.
 
You  will  need  to  use  your  Android  Market  public  key  to  perform  
the  signature  verification.  The  
following  procedure  shows  you  how  to  retrieve  Base64
-­‐
encoded  public  key  from  the  Android  Market  
publisher  site.
 
1.

Log  in  to  your  
publisher  account
.
 
2.

On  the  upper  left  part  of  th
e  page,  under  your  name,  click  
Edit  profile
.
 
3.

On  the  Edit  Profile  page,  scroll  down  to  the  Licensing  &  In
-­‐
app  Billing  panel  (see  figure  2).
 
4.

Copy  your  public  key.
 
Important
:  To  keep  your  public  key  safe  from  malicious  users  and  hackers,  do  not  embed  your  pub
lic  
key  as  an  entire  literal  string.  Instead,  construct  the  string  at  runtime  from  pieces  or  use  bit  
manipulation  (for  example,  XOR  with  some  other  string)  to  hide  the  actual  key.  The  key  itself  is  not  
secret  information,  but  you  do  not  want  to  make  it  eas
y  for  a  hacker  or  malicious  user  to  replace  the  
public  key  with  another  key.
 

Figure  2.
 
The  Licensing  and  In
-­‐
app  Billing  panel  of  your  account

s  Edit  Profile  page  lets  you  see  your  
public  key.
 
Modifying  Your  Application  Code
 
After  you  finish  adding  in
-­‐
app
 
billing  components  to  your  project,  you  are  ready  to  modify  your  
application

s  code.  For  a  typical  implementation,  like  the  one  that  is  demonstrated  in  the  sample  
application,  this  means  you  need  to  write  code  to  do  the  following:
 


Create  a  storage  mechani
sm  for  storing  users

 
purchase  information.
 


Create  a  user  interface  that  lets  users  select  items  for  purchase.
 
The  sample  code  in  
Dungeons.java
 
shows  you  how  to  do  both  of  these  tasks.
 
Creating  a  storage  mechanism  for  storing  purchase  information
 
You  must  
set  up  a  database  or  some  other  mechanism  for  storing  users

 
purchase  information.  The  
sample  application  provides  an  example  database  (PurchaseDatabase.java);  however,  the  example  
database  has  been  simplified  for  clarity  and  does  not  exhibit  the  security  
best  practices  that  we  
recommend.  If  you  have  a  remote  server,  we  recommend  that  you  store  purchase  information  on  your  
server  instead  of  in  a  local  database  on  a  device.  For  more  information  about  security  best  practices,  
see  
Security  and  Design
.
 
Note
:  If  you  store  any  purchase  information  on  a  device,  be  sure  to  encrypt  the  data  and  use  a  device
-­‐
specific  encryption  key.  Also,  if  the  purchase  type  for  any  of  your  
items  is  

unmanaged,

 
we  
recommend  that  you  back  up  the  purchase  information  for  these  items  to  a  remote  server  or  use  
Android

s  
data  backup
 
framework  to  back  up  the  purchase  inform
ation.  Backing  up  purchase  
information  for  unmanaged  items  is  important  because  unmanaged  items  cannot  be  restored  by  using  
the  
RESTORE_TRANSACTIONS
 
request  type.
 
Creating  a  user  interface  for  selecting  items
 
You  must  provide  users  with  a  means  for  selecti
ng  items  that  they  want  to  purchase.  Android  Market  
provides  the  checkout  user  interface  (which  is  where  the  user  provides  a  form  of  payment  and  
approves  the  purchase),  but  your  application  must  provide  a  control  (widget)  that  invokes  the  
sendBillingReques
t()
 
method  when  a  user  selects  an  item  for  purchase.
 
You  can  render  the  control  and  trigger  the  
sendBillingRequest()
 
method  any  way  you  want.  
The  sample  application  uses  a  spinner  widget  and  a  button  to  present  items  to  a  user  and  trigger  a  
billing  request  (see  
Dungeons.java
).  The  user  interface  also  shows  a  list  of  recently  purchased  
items.
 
 
Security  and  Design
 
As  you
 
design  your  in
-­‐
app  billing  implementation,  be  sure  to  follow  the  security  and  design  guidelines  
that  are  discussed  in  this  document.  These  guidelines  are  recommended  best  practices  for  anyone  
who  is  using  Android  Market

s  in
-­‐
app  billing  service.
 
Security  
Best  Practices
 
Perform  signature  verification  tasks  on  a  server
 
If  practical,  you  should  perform  signature  verification  on  a  remote  server  and  not  on  a  device.  
Implementing  the  verification  process  on  a  server  makes  it  difficult  for  attackers  to  break  the  
verification  process  by  reverse  engineering  your  .apk  file.  If  you  do  offload  security  processing  to  a  
remote  server,  be  sure  that  the  device
-­‐
server  handshake  is  secure.
 
Protect  your  unlocked  content
 
To  prevent  malicious  users  from  redistributing  your  unlo
cked  content,  do  not  bundle  it  in  your  .apk  
file.  Instead,  do  one  of  the  following:
 
8.

Use  a  real
-­‐
time  service  to  deliver  your  content,  such  as  a  content  feed.  Delivering  content  
through  a  real
-­‐
time  service  allows  you  to  keep  your  content  fresh.
 
9.

Use  a  remote  
server  to  deliver  your  content.
 
When  you  deliver  content  from  a  remote  server  or  a  real
-­‐
time  service,  you  can  store  the  unlocked  
content  in  device  memory  or  store  it  on  the  device

s  SD  card.  If  you  store  content  on  an  SD  card,  be  
sure  to  encrypt  the  conten
t  and  use  a  device
-­‐
specific  encryption  key.
 
Obfuscate  your  code
 
You  should  obfuscate  your  in
-­‐
app  billing  code  so  it  is  difficult  for  an  attacker  to  reverse  engineer  
security  protocols  and  other  application  components.  At  a  minimum,  we  recommend  that  you  ru
n  an  
obfuscation  tool  like  
Proguard
 
on  your  code.
 
In  addition  to  running  an  obfuscation  program,  we  recommend  that  you  use  the  following  techniques  
to  obfuscate  your  in
-­‐
app  b
illing  code.
 
6.

Inline  methods  into  other  methods.
 
7.

Construct  strings  on  the  fly  instead  of  defining  them  as  constants.
 
8.

Use  Java  reflection  to  call  methods.
 
Using  these  techniques  can  help  reduce  the  attack  surface  of  your  application  and  help  minimize  
attacks
 
that  can  compromise  your  in
-­‐
app  billing  implementation.
 
Note:
 
If  you  use  Proguard  to  obfuscate  your  code,  you  must  add  the  following  line  to  your  Proguard  
configuration  file:
 


keep  class  com.android.vending.billing.**

Modify  all  sample  application  code
 
The
 
in
-­‐
app  billing  sample  application  is  publicly  distributed  and  can  be  downloaded  by  anyone,  which  
means  it  is  relatively  easy  for  an  attacker  to  reverse  engineer  your  application  if  you  use  the  sample  
code  exactly  as  it  is  published.  The  sample  application
 
is  intended  to  be  used  only  as  an  example.  If  
you  use  any  part  of  the  sample  application,  you  must  modify  it  before  you  publish  it  or  release  it  as  
part  of  a  production  application.
 
In  particular,  attackers  look  for  known  entry  points  and  exit  points  in  a
n  application,  so  it  is  important  
that  you  modify  these  parts  of  your  code  that  are  identical  to  the  sample  application.
 
Use  secure  random  nonces
 
Nonces  must  not  be  predictable  or  reused.  Always  use  a  cryptographically  secure  random  number  
generator  (like  
SecureRandom
)  when  you  generate  nonces.  This  can  help  reduce  replay  attacks.
 
Also,  if  you  are  performing  nonce  verification  on  a  server,  make  sure  that  you  generate  the  
nonces  on  
the  server.
 
Take  action  against  trademark  and  copyright  infringement
 
If  you  see  your  content  being  redistributed  on  Android  Market,  act  quickly  and  decisively.  File  a  
trademark  notice  of  infringement
 
or  a  
copyright  notice  of  infringement
.
 
Implement  a  revocability  scheme  for  unlocked  content
 
If  you  are  using  a  remote  server  to  deliver  or  manage  content,  have  
your  application  verify  the  
purchase  state  of  the  unlocked  content  whenever  a  user  accesses  the  content.  This  allows  you  to  
revoke  use  when  necessary  and  minimize  piracy.
 
Protect  your  Android  Market  public  key
 
To  keep  your  public  key  safe  from  malicious  us
ers  and  hackers,  do  not  embed  it  in  any  code  as  a  literal  
string.  Instead,  construct  the  string  at  runtime  from  pieces  or  use  bit  manipulation  (for  example,  XOR  
with  some  other  string)  to  hide  the  actual  key.  The  key  itself  is  not  secret  information,  but  y
ou  do  not  
want  to  make  it  easy  for  a  hacker  or  malicious  user  to  replace  the  public  key  with  another  key.
 
Testing  In
-­‐
app  Billing
 
The  Android  Market  publisher  site  provides  several  tools  that  help  you  test  your  in
-­‐
app  billing  
implementation  before  it  is  pu
blished.  You  can  use  these  tools  to  create  test  accounts  and  purchase  
special  reserved  items  that  send  static  billing  responses  to  your  application.
 
To  test  in
-­‐
app  billing  in  an  application  you  must  install  the  application  on  an  Android
-­‐
powered  device.  
You
 
cannot  use  the  Android  emulator  to  test  in
-­‐
app  billing.  The  device  you  use  for  testing  must  run  a  
standard  version  of  the  Android  1.6  or  later  platform  (API  level  4  or  higher),  and  have  the  most  current  
version  of  the  Android  Market  application  installed.
 
If  a  device  is  not  running  the  most  current  Android  
Market  application,  your  application  won

t  be  able  to  send  in
-­‐
app  billing  requests  to  Android  Market.  
For  general  information  about  how  to  set  up  a  device  for  use  in  developing  Android  applications,  see  
Using  Hardware  Devices
.
 
The  following  section  shows  you  how  to  set  up  and  use  the  in
-­‐
app  billing  test  tools.
 
Testing  in
-­‐
app  purchases  with  static  responses
 
We  recommend  that  you  firs
t  test  your  in
-­‐
app  billing  implementation  using  static  responses  from  
Android  Market.  This  enables  you  to  verify  that  your  application  is  handling  the  primary  Android  
Market  responses  correctly  and  that  your  application  is  able  to  verify  signatures  correct
ly.
 
To  test  your  implementation  with  static  responses,  you  make  an  in
-­‐
app  billing  request  using  a  special  
item  that  has  a  reserved  product  ID.  Each  reserved  product  ID  returns  a  specific  static  response  from  
Android  Market.  No  money  is  transferred  when  you
 
make  in
-­‐
app  billing  requests  with  the  reserved  
product  IDs.  Also,  you  cannot  specify  the  form  of  payment  when  you  make  a  billing  request  with  a  
reserved  product  ID.  Figure  1  shows  the  checkout  flow  for  the  reserved  item  that  has  the  product  ID  
android.tes
t.purchased.
 

Figure  1.
 
Checkout  flow  for  the  special  reserved  item  android.test.purchased.
 
You  do  not  need  to  list  the  reserved  products  in  your  application

s  product  list.  Android  Market  
already  knows  about  the  reserved  product  IDs.  Also,  you  do  not  
need  to  upload  your  application  to  
the  publisher  site  to  perform  static  response  tests  with  the  reserved  product  IDs.  You  can  simply  
install  your  application  on  a  device,  log  into  the  device,  and  make  billing  requests  using  the  reserved  
product  IDs.
 
There  
are  four  reserved  product  IDs  for  testing  static  in
-­‐
app  billing  responses:
 
10.

android.test.purchased
When  you  make  an  in
-­‐
app  billing  request  with  this  product  ID,  Android  
Market  responds  as  though  you  successfully  purchased  an  item.  The  response  includes  a  JSO
N  
string,  which  contains  fake  purchase  information  (for  example,  a  fake  order  ID).  In  some  cases,  
the  JSON  string  is  signed  and  the  response  includes  the  signature  so  you  can  test  your  
signature  verification  implementation  using  these  responses.
 
11.

android.te
st.canceled
When  you  make  an  in
-­‐
app  billing  request  with  this  product  ID  Android  
Market  responds  as  though  the  purchase  was  canceled.  This  can  occur  when  an  error  is  
encountered  in  the  order  process,  such  as  an  invalid  credit  card,  or  when  you  cancel  a  user

s  
order  before  it  is  charged.
 
12.

android.test.refunded
When  you  make  an  in
-­‐
app  billing  request  with  this  product  ID,  Android  
Market  responds  as  though  the  purchase  was  refunded.  Refunds  cannot  be  initiated  through  
Android  Market

s  in
-­‐
app  billing  service.  Refu
nds  must  be  initiated  by  you  (the  merchant).  After  
you  process  a  refund  request  through  your  Google  Checkout  account,  a  refund  message  is  sent  
to  your  application  by  Android  Market.  This  occurs  only  when  Android  Market  gets  notification  
from  Google  Checkou
t  that  a  refund  has  been  made.  For  more  information  about  refunds,  see  
Handling  IN_APP_NOTIFY  messages
 
and  
In
-­‐
app  Billing  Pricing
.
 
13.

android.test.item_unavailable
When  you  make  an  in
-­‐
app  billing  request  with  this  product  ID,  
Android  Market  responds  as  though  the  item  being  purchased  was  not  listed  in  your  
appl
ication

s  product  list.
 
In  some  cases,  the  reserved  items  may  return  signed  static  responses,  which  lets  you  test  signature  
verification  in  your  application.  To  test  signature  verification  with  the  special  reserved  product  IDs,  
you  may  need  to  set  up  
test  accounts
 
or  upload  your  application  as  a  unpublished  draft  application.  
Table  1  shows  you  the  conditions  under  which  static  responses  are  signed
.
 
Table  1.
 
Conditions  under  which  static  responses  are  signed.
 
Application ever
been published?

Draft application
uploaded and
unpublished?

User who is
running the
application

Static
response
signature

No

No

Any

Unsigned

No

No

Developer

Signed

Yes

No

Any

Unsigned

Yes

No

Developer

Signed

Yes

No

Test account

Signed

Yes

Yes

Any

Signed

To  make  an  in
-­‐
app  billing  request  with  a  reserved  product  ID,  you  simply  construct  a  normal  
REQUEST_PURCHASE
 
request,  but  instead  of  using  a  real  product  ID  from  your  application

s  product  
list  you  use  one  of  the  reserved  product  IDs.
 
To  test  your  application  using  the  reserved  product  IDs,  follow  these  steps:
 
9.

Install  your  application  on  an  Android
-­‐
powered  
device.
You  cannot  use  the  emulator  to  test  in
-­‐
app  billing;  you  must  install  your  application  on  a  device  to  test  in
-­‐
app  billing.  To  learn  how  to  
install  an  application  on  a  device,  see  
Running  on  a  device
.
 
10.

Sign  in  to  your  device  with  your  developer  account.
You  do  not  need  to  use  a  test  account  if  
you  are  testing  only  with  the  reserved  product  IDs.
 
11.

Verify  that  your  device  is  running  a  supported  v
ersion  of  the  Android  Market  application  or  
the  MyApps  application.
If  your  device  is  running  Android  3.0,  in
-­‐
app  billing  requires  version  
5.0.12  (or  higher)  of  the  MyApps  application.  If  your  device  is  running  any  other  version  of  
Android,  in
-­‐
app  billing  r
equires  version  2.3.4  (or  higher)  of  the  Android  Market  application.  To  
learn  how  to  check  the  version  of  the  Android  Market  application,  see  
Updating  Android  
Market
.
 
12.

Run  your  ap
plication  and  purchase  the  reserved  product  IDs.
 
Note
:  Making  in
-­‐
app  billing  requests  with  the  reserved  product  IDs  overrides  the  usual  Android  
Market  production  system.  When  you  send  an  in
-­‐
app  billing  request  for  a  reserved  product  ID,  the  
quality  of  serv
ice  will  not  be  comparable  to  the  production  environment.
 
Testing  In
-­‐
app  Purchases  Using  Your  Own  Product  IDs
 
After  you  finish  your  static  response  testing,  and  you  verify  that  signature  verification  is  working  in  
your  application,  you  can  test  your  in
-­‐
app
 
billing  implementation  by  making  actual  in
-­‐
app  purchases.  
Testing  real  in
-­‐
app  purchases  enables  you  to  test  the  end
-­‐
to
-­‐
end  in
-­‐
app  billing  experience,  including  
the  actual  responses  from  Android  Market  and  the  actual  checkout  flow  that  users  will  experienc
e  in  
your  application.
 
Note
:  You  do  not  need  to  publish  your  application  to  do  end
-­‐
to
-­‐
end  testing.  You  only  need  to  upload  
your  application  as  a  draft  application  to  perform  end
-­‐
to
-­‐
end  testing.
 
To  test  your  in
-­‐
app  billing  implementation  with  actual  in
-­‐
app  
purchases,  you  will  need  to  register  at  
least  one  test  account  on  the  Android  Market  publisher  site.  You  cannot  use  your  developer  account  
to  test  the  complete  in
-­‐
app  purchase  process  because  Google  Checkout  does  not  let  you  buy  items  
from  yourself.  If  you
 
have  not  set  up  test  accounts  before,  see  
Setting  up  test  accounts
.
 
Also,  a  test  account  can  purchase  an  item  in  your  product  list  only  if  the  
item  is  published.  The  
application  does  not  need  to  be  published,  but  the  item  does  need  to  be  published.
 
When  you  use  a  test  account  to  purchase  items,  the  test  account  is  billed  through  Google  Checkout  
and  your  Google  Checkout  Merchant  account  receives  a
 
payout  for  the  purchase.  Therefore,  you  may  
want  to  refund  purchases  that  are  made  with  test  accounts,  otherwise  the  purchases  will  show  up  as  
actual  payouts  to  your  merchant  account.
 
To  test  your  in
-­‐
app  billing  implementation  with  actual  purchases,  follo
w  these  steps:
 


Upload  your  application  as  a  draft  application  to  the  publisher  site.
You  do  not  need  to  publish  
your  application  to  perform  end
-­‐
to
-­‐
end  testing  with  real  product  IDs;  you  only  need  to  upload  
your  application  as  a  draft  application.  However,  y
ou  must  sign  your  application  with  your  
release  key  before  you  upload  it  as  a  draft  application.  Also,  the  version  number  of  the  
uploaded  application  must  match  the  version  number  of  the  application  you  load  to  your  
device  for  testing.  To  learn  how  to  uplo
ad  an  application  to  Android  Market,  see  
Uploading  
applications
.
 


Add  items  to  the  application

s  product  list.
Make  sure  that  you  publish  the  items  (the  
application  can  remain  unpu
blished).  See  
Creating  a  product  list
 
to  learn  how  to  do  this.
 


Install  your  application  on  an  Android
-­‐
powered  device.
You  cannot  use  the  emulator  to  te
st  in
-­‐
app  billing;  you  must  install  your  application  on  a  device  to  test  in
-­‐
app  billing.  To  learn  how  to  
install  an  application  on  a  device,  see  
Running  on  a  device
.
 


Make  one  of  your  test  accounts  the  primary  account  on  your  device.
To  perform  end
-­‐
to
-­‐
end  
testing  of  in
-­‐
app  billing,  the  prim
ary  account  on  your  device  must  be  one  of  the  
test  accounts
 
that  you  registered  on  the  Android  Market  site.  If  the  primary  account  on  your  devic
e  is  not  a  
test  account,  you  must  do  a  factory  reset  of  the  device  and  then  sign  in  with  one  of  your  test  
accounts.  To  perform  a  factory  reset,  do  the  following:
 

Open  Settings  on  your  device.
 

Touch  
Privacy
.
 

Touch  Factory  data  reset.
 

Touch  Reset  phone.
 

Afte
r  the  phone  resets,  be  sure  to  sign  in  with  one  of  your  test  accounts  during  the  device  
setup  process.
 


Verify  that  your  device  is  running  a  supported  version  of  the  Android  Market  application  or  
the  MyApps  application.
If  your  device  is  running  Android  3.0,
 
in
-­‐
app  billing  requires  version  
5.0.12  (or  higher)  of  the  MyApps  application.  If  your  device  is  running  any  other  version  of  
Android,  in
-­‐
app  billing  requires  version  2.3.4  (or  higher)  of  the  Android  Market  application.  To  
learn  how  to  check  the  version  of
 
the  Android  Market  application,  see  
Updating  Android  
Market
.
 


Make  in
-­‐
app  purchases  in  your  application.
 
Note:
 
The  only  way  to  change  the  primary  account  on  a  device  is  to  do  a  f
actory  reset,  making  sure  
you  log  on  with  your  primary  account  first.
 
When  you  are  finished  testing  your  in
-­‐
app  billing  implementation,  you  are  ready  to  publish  your  
application  on  Android  Market.  You  can  follow  the  normal  steps  for  
preparing
,  
signing
,  and  
publishing  
your  application
.
 
Administering  In
-­‐
app  Billing
 
In
-­‐
app  billing  frees  you  from  processing  financial  transactions,  but  you  still  need  to  perform  a  few  
administrative  tasks,  including  setting  up  and  maintaining  your  product  list  on  the  publisher  si
te,  
registering  test  accounts,  and  handling  refunds  when  necessary.
 
You  must  have  an  Android  Market  publisher  account  to  register  test  accounts.  And  you  must  have  a  
Google  Checkout  Merchant  account  to  create  a  product  list  and  issue  refunds  to  your  users.  
If  you  
already  have  a  publisher  account  on  Android  Market,  you  can  use  your  existing  account.  You  do  not  
need  to  register  for  a  new  account  to  support  in
-­‐
app  billing.  If  you  do  not  have  a  publisher  account,  
you  can  register  as  an  Android  Market  developer  a
nd  set  up  a  publisher  account  at  the  Android  
Market  
publisher  site
.  If  you  do  not  have  a  Google  Checkout  Merchant  account,  you  can  register  for  
one  at  the  
Google  
Checkout  site
.
 
Creating  a  Product  List
 
The  Android  Market  publisher  site  provides  a  product  list  for  each  of  your  published  applications.  You  
can  sell  an  item  using  Android  Market

s  in
-­‐
app  billing  feature  only  if  the  item  is  listed  on  an  
application

s  prod
uct  list.  Each  application  has  its  own  product  list;  you  cannot  sell  items  that  are  listed  
in  another  application

s  product  list.
 
You  can  access  an  application

s  product  list  by  clicking  the  
In
-­‐
App  Products
 
link  that  appears  under  
each  of  the  applications  
that  are  listed  for  your  publisher  account  (see  figure  1).  The  
In
-­‐
App  Products
 
link  appears  only  if  you  have  a  Google  Checkout  Merchant  account  and  an  application

s  manifest  
includes  the  
com.android.vending.BILLING
 
permission.
 

Figure  1.
 
You  can  access  an
 
application

s  product  list  by  clicking  the  
In
-­‐
App  Products
 
link.
 
A  product  list  contains  information  about  the  items  you  are  selling,  such  as  a  product  id,  product  
description,  and  price  (see  figure  2).  The  product  list  stores  only  metadata  about  the  item
s  you  are  
selling  in  your  application.  It  does  not  store  any  digital  content.  You  are  responsible  for  storing  and  
delivering  the  digital  content  that  you  sell  in  your  applications.
 

Figure  2.
 
An  application

s  product  list.
 
You  can  create  a  product  list  fo
r  a  published  application  or  a  draft  application  that

s  been  uploaded  
and  saved  to  the  Android  Market  site.  However,  you  must  have  a  Google  Checkout  Merchant  account  
and  the  application

s  manifest  must  include  the  
com.android.vending.BILLING
 
permission.  If  
an  application

s  manifest  does  not  include  this  permission,  you  will  be  able  to  edit  existing  items  in  the  
product  list  but  you  will  not  be  able  to  add  new  items  to  the  list.  For  more  information,  see  
Modifying  
your  application

s  AndroidMan
ifest.xml  file
.
 
To  create  a  product  list  for  an  application,  follow  these  steps:
 
14.

Log  in
 
to  your  publisher  account.
 
15.

In  the  
All  Android  Market  listings
 
panel,  under  the  application  name,  click  
In
-­‐
app  Products
.
 
16.

On  the  In
-­‐
app  Products  List  page,  click  
Add  in
-­‐
app  product
.
 
17.

On  the  Create  New  In
-­‐
app  Product  page  (see  figure  3),  provide  details  about  the  item  you  are  
selling  and  then  click  
Save
.
 

Figure  3.
 
The  Create  New  In
-­‐
app  Product  page  lets  you  add  items  to  an  application

s  product  list.
 
You  must  enter  the  following  information  for  each  item  in  a  product  list:
 
13.

In
-­‐
app  Product  ID
Product  IDs  are  unique  across  an  application

s  namespace.  A  product  ID  must  
start  with  a  lowercase  letter  or  a  number,  and  must  be  composed  using  only  lowercase  letters  
(a
-­‐
z),  numbers  (0
-­‐
9),  underlines  (_),  and  dots  (.).  The  product  ID  

android.test

 
is  reserved,  as  
are  all  product  IDs  that  start  with  

android.test.

 
In  addition,  
you  cannot  modify  an  item

s  
product  ID  after  it  is  created,  and  you  cannot  reuse  a  product  ID,  even  if  you  delete  the  item  
previously  using  the  product  ID.
 
14.

Purchase  type
The  purchase  type  can  be  

managed  per  user  account

 
or  

unmanaged.

 
You  
can  specify  an  
item

s  purchase  type  only  through  the  publisher  site  and  you  can  never  change  
an  item

s  purchase  type  once  you  specify  it.  For  more  information,  see  
Choosing  a  purchase  
type
 
later  in  this  document.
 
15.

Publishing  State
An  item

s  publishing  state  can  be  

publish
ed

 
or  

unpublished.

 
However,  to  
be  visible  to  a  user  during  checkout,  an  item

s  publishing  state  must  be  set  to  

published

 
and  
the  item

s  application  must  be  published  on  Android  Market.  
Note:
 
This  is  not  true  for  test  
accounts.  An  item  is  visible  to  a  
test  account  if  the  application  is  not  published  and  the  item  is  
published.  See  
Testing  In
-­‐
app  Billing
 
for  more  information.
 
16.

Language
A
 
product  list  inherits  its  language  from  the  parent  application.
 
17.

Title
The  title  is  a  short  descriptor  for  the  item.  For  example,  

Sleeping  potion.

 
Titles  must  be  
unique  across  an  application

s  namespace.  Every  item  must  have  a  title.  The  title  is  visible  
to  
users  during  checkout.  For  optimum  appearance,  titles  should  be  no  longer  than  25  characters;  
however,  titles  can  be  up  to  55  characters  in  length.
 
18.

Description
The  description  is  a  long  descriptor  for  the  item.  For  example,  

Instantly  puts  
creatures  to  s
leep.  Does  not  work  on  angry  elves.

 
Every  item  must  have  a  description.  The  
description  is  visible  to  users  during  checkout.  Descriptions  can  be  up  to  80  characters  in  
length.
 
19.

Price
Every  item  must  have  a  price  greater  than  zero;  you  cannot  set  a  price  of  

0

 
(free).
 
For  more  information  about  product  IDs  and  product  lists,  see  
Creating  In
-­‐
App  Product  IDs
.  For  
more  information  about  pricing,  see  
In
-­‐
App  Billing  Pricing
.
 
Note
:  Be  sure  to  plan  your  product  ID  namespace.  You  cannot  reuse  or  modify  product  IDs  after  
you  save  them.
 
Choosing  a  Purchase  Type
 
An  item

s  purchase  type  controls  how  Android  Market  m
anages  the  purchase  of  the  item.  There  are  
two  purchase  types:  

managed  per  user  account

 
and  

unmanaged.

 
Items  that  are  managed  per  user  account  can  be  purchased  only  once  per  user  account.  When  an  item  
is  managed  per  user  account,  Android  Market  permane
ntly  stores  the  transaction  information  for  
each  item  on  a  per
-­‐
user  basis.  This  enables  you  to  query  Android  Market  with  the  
RESTORE_TRANSACTIONS
 
request  and  restore  the  state  of  the  items  a  specific  user  has  purchased.
 
If  a  user  attempts  to  purchase  a  man
aged  item  that  has  already  been  purchased,  Android  Market  
displays  an  

Item  already  purchased

 
error.  This  occurs  during  checkout,  when  Android  Market  
displays  the  price  and  description  information  on  the  checkout  page.  When  the  user  dismisses  the  
error  me
ssage,  the  checkout  page  disappears  and  the  user  returns  to  your  user  interface.  As  a  best  
practice,  your  application  should  prevent  the  user  from  seeing  this  error.  The  sample  application  
demonstrates  how  you  can  do  this  by  keeping  track  of  items  that  are
 
managed  and  already  purchased  
and  not  allowing  users  to  select  those  items  from  the  list.  Your  application  should  do  something  
similar

either  graying  out  the  item  or  hiding  it  so  that  it  cannot  be  selected.
 
The  

manage  by  user  account

 
purchase  type  is  useful  if  you  are  selling  items  such  as  game  levels  or  
application  features.  These  items  are  not  transient  and  usually  need  to  be  restored  whenever  a  user  
reinstalls  your  application,  wipes  the  data  on  their  device,  or  installs  your  appli
cation  on  a  new  device.
 
Items  that  are  unmanaged  do  not  have  their  transaction  information  stored  on  Android  Market,  which  
means  you  cannot  query  Android  Market  to  retrieve  transaction  information  for  items  whose  
purchase  type  is  listed  as  unmanaged.  You  a
re  responsible  for  managing  the  transaction  information  
of  unmanaged  items.  Also,  unmanaged  items  can  be  purchased  multiple  times  as  far  as  Android  
Market  is  concerned,  so  it

s  also  up  to  you  to  control  how  many  times  an  unmanaged  item  can  be  
purchased.
 
Th
e  

unmanaged

 
purchase  type  is  useful  if  you  are  selling  consumable  items,  such  as  fuel  or  magic  
spells.  These  items  are  consumed  within  your  application  and  are  usually  purchased  multiple  times.
 
Handling  Refunds
 
In
-­‐
app  billing  does  not  allow  users  to  send
 
a  refund  request  to  Android  Market.  Refunds  for  in
-­‐
app  
purchases  must  be  directed  to  you  (the  application  developer).  You  can  then  process  the  refund  
through  your  Google  Checkout  Merchant  account.  When  you  do  this,  Android  Market  receives  a  
refund  notific
ation  from  Google  Checkout,  and  Android  Market  sends  a  refund  message  to  your  
application.  For  more  information,  see  
Handling  IN_APP_NOTIFY  m
essages
 
and  
In
-­‐
app  Billing  Pricing
.
 
Important:
 
You  cannot  use  the  Google  Checkout  API  to  issue  refunds  or  cancel  in
-­‐
app  billing  
transactions.  You  must  do  this  manually
 
through  your  Google  Checkout  merchant  account.  However,  
you  can  use  the  Google  Checkout  API  to  retrieve  order  information.
 
Setting  Up  Test  Accounts
 
The  Android  Market  publisher  site  lets  you  set  up  one  or  more  test  accounts.  A  test  account  is  a  
regular  Go
ogle  account  that  you  register  on  the  publisher  site  as  a  test  account.  Test  accounts  are  
authorized  to  make  in
-­‐
app  purchases  from  applications  that  you  have  uploaded  to  the  Android  Market  
site  but  have  not  yet  published.
 
You  can  use  any  Google  account  as  
a  test  account.  Test  accounts  are  useful  if  you  want  to  let  multiple  
people  test  in
-­‐
app  billing  on  applications  without  giving  them  access  to  your  publisher  account

s  sign
-­‐
in  credentials.  If  you  want  to  own  and  control  the  test  accounts,  you  can  create  the
 
accounts  yourself  
and  distribute  the  credentials  to  your  developers  or  testers.
 
Test  accounts  have  three  limitations:
 


Test  account  users  can  make  purchase  requests  only  within  applications  that  are  already  
uploaded  to  your  publisher  account  (although  the  
application  doesn

t  need  to  be  published).
 


Test  accounts  can  only  be  used  to  purchase  items  that  are  listed  (and  published)  in  an  
application

s  product  list.
 


Test  account  users  do  not  have  access  to  your  publisher  account  and  cannot  upload  
applications  to  
your  publisher  account.
 
To  add  test  accounts  to  your  publisher  account,  follow  these  steps:
 


Log  in
 
to  your  publisher  account.
 


On  the  upper  left  part  of  the  page,  under  your  name,  click  
Edit  profile
.
 


On  the  
Edit  Profile  page,  scroll  down  to  the  Licensing  &  In
-­‐
app  Billing  panel  (see  figure  4).
 


In  Test  Accounts,  add  the  email  addresses  for  the  test  accounts  you  want  to  register,  
separating  each  account  with  a  comma.
 


Click  
Save
 
to  save  your  profile  changes.
 

Fi
gure  4.
 
The  Licensing  and  In
-­‐
app  Billing  panel  of  your  account

s  Edit  Profile  page  lets  you  register  
test  accounts.
 
Where  to  Get  Support
 
If  you  have  questions  or  encounter  problems  while  implementing  in
-­‐
app  billing,  contact  the  support  
resources  listed  in  
the  following  table  (see  table  2).  By  directing  your  queries  to  the  correct  forum,  you  
can  get  the  support  you  need  more  quickly.
 
Table  2.
 
Developer  support  resources  for  Android  Market  in
-­‐
app  billing.
 
Support
Type

Resource

Range of Topics

Developm
ent and

testing
issues

Google Groups:
android
-
developers

In
-
app billing integration
questions, user experience ideas,
handling of responses,
obfuscating code, IPC, test
environment setup.

Stack Overflow:
http://stackoverflow.com/questions/ta
gged/ android

Market
billing
issue
tracker

Market billing project issue
tracker

Bug and issue reports related
specifically to in
-
app billing sample
code.

For  general  information  about  how  to  post  to  the  groups  listed  above,  see  
Developer  Forums
 
docum
ent  in  the  Resources  tab.
 
In
-­‐
app  Billing  Reference
 
The  following  document  provides  technical  reference  information  for  the  following:
 
18.

Android  Market  Server  Response  Codes  for  In
-­‐
app  Billing
 
19.

In
-­‐
app  Billing  Interface  Parameters
 
20.

In
-­‐
app  Billing  Broadcast  
Intents
 

Android  Market  Server  Response  Codes  for  In
-­‐
app  Billing
 
The  following  table  lists  all  of  the  server  response  codes  that  are  sent  from  Android  Market  to  your  
application.  Android  Market  sends  these  response  codes  asynchronously  as  
response_code
 
ext
ras  in  the  
com.android.vending.billing.RESPONSE_CODE
 
broadcast  intent.  Your  
application  must  handle  all  of  these  response  codes.
 
Table  1.
 
Summary  of  response  codes  returned  by  Android  Market.
 
Response Code

Value

Description

RESULT_OK

0

Indicates that the request was sent to the server successfully. When this code is
returned in response to a
CHECK_BILLING_SUPPORTED

request, indicates that
billing is supported.

RESULT_USER_C
ANCELED

1

Indicates that the user pressed the back button on the

checkout page instead of
buying the item.

RESULT_SERVIC
E_UNAVAILABLE

2

Indicates that the network connection is down.

RESULT_BILLIN
G_UNAVAILABLE

3

Indicates that in
-
app billing is not available because the
API_VERSION

that you
specified is not recognize
d by the Android Market application or the user is
ineligible for in
-
app billing (for example, the user resides in a country that prohibits
in
-
app purchases).

RESULT_ITEM_U
NAVAILABLE

4

Indicates that Android Market cannot find the requested item in the ap
plication

s
product list. This can happen if the product ID is misspelled in your
REQUEST_PURCHASE

request or if an item is unpublished in the application

s
product list.

RESULT_DEVELO
PER_ERROR

5

Indicates that an application is trying to make an in
-
app billing request but the
application has not declared the com.android.vending.BILLING permission in its
manifest. Can also indicate that an application is not properly signed, or that you
sent a malf
ormed request, such as a request with missing Bundle keys or a request
that uses an unrecognized request type.

RESULT_ERROR

6

Indicates an unexpected server error. For example, this error is triggered if you try
to purchase an item from yourself, which is

not allowed by Google Checkout.


In
-­‐
app  Billing  Service  Interface
 
The  following  section  describes  the  interface  for  Android  Market

s  in
-­‐
app  billing  service.  The  interface  
is  defined  in  the  
IMarketBillingService.aidl
 
file,  which  is  included  with  the  in
-­‐
app  billing  
sample  application
.
 
The  interface  consists  of  a  single  request  method  
sendBillingRequest()
.  This
 
method  takes  a  
single  
Bundle
 
parameter.  The  Bundle  parameter  includes  several  key
-­‐
value  pairs,  which  are  
summarized  in  table  2.
 
Table  2.
 
Description  of  Bundle  keys  passed  in  a  
s
endBillingRequest()
 
request.
 
Key

Type

Possible Values

Require
d?

Description

BILLING
_REQUES
Strin
g

CHECK_BILLING_SUPPORT
ED
,
Yes

The type of billing request you
are making with the
T

REQUEST_PURCHASE
,
GET_P
URCHASE_INFORMATION
,
CO
NFIRM_NOTIFICATIONS
, or
RESTORE_TRANSACTIONS

sendBillingRequest()

request. The possible values are
discussed more below this table.

API_VER
SION

int

1

Yes

The version of Android Market

s
in
-
app billing service you are
using. The current version is
1.

PACKAGE
_NAME

Strin
g

A valid package name.

Yes

The name of the application that
is making the request.

ITEM_ID

Strin
g

Any valid product identifier.

Required
for
REQUES
T_PURC
HASE

requests.

The product ID of the item you
are making a billing request for.

Every in
-
app item that you sell
using Android Market

s in
-
app
billing service must have a
unique product ID, which you
specify on the Android Market
publisher site.

NONCE

long

Any valid
long

value.

Required
for
GET_PU
RCHASE
_INFOR
MATION

and
RESTOR
E_
TRAN
SACTIO
NS

requests.

A number used once. Your
application must generate and
send a nonce with each
GET_PURCHASE_INFORMATION

and
RESTORE_TRANSACTIONS

request. The nonce is returned
with the
PURCHASE_STATE_CHANGED

broadcast intent, so you can use
this val
ue to verify the integrity
of transaction responses form
Android Market.

NOTIFY_
IDS

Array of
long

values

Any valid array of
long

values

Required
for
GET_PU
RCHASE
_INFOR
MATION

and
CONFIR
M_NOTI
FICATI
ONS
requ
ests.

An array of notification
identifiers. A notification ID is
sent to your application in an
IN_APP_NOTIFY

broadcast
intent every time a purchase
changes state. You use the
notification to retrieve the details
of the purchase state change.

DEVELOP
ER_PAYL
OAD

Strin
g

Any valid
String

less than 256
characters long.

No

A developer
-
specified string that
can be specified when you
make a
REQUEST_PURCHASE

request. This field is returned in
the JSON string that contains
transaction information for an
order. You can use
this key to
send supplemental information
with an order. For example, you
can use this key to send index
keys with an order, which is
useful if you are using a
database to store purchase
information. We recommend
that you do not use this key to
send data o
r content.

The  
BILLING_REQUEST
 
key  can  have  the  following  values:
 
20.

CHECK_BILLING_SUPPORTED
This
 
request  verifies  that  the  Android  Market  application  
supports  in
-­‐
app  billing.  You  usually  send  this  request  when  your  application  first  starts  up.  This  
request  is  useful  if  you  want  to  enable  or  disable  certain  UI  features  that  are  relevant  only  to  in
-­‐
app
 
billing.
 
21.

REQUEST_PURCHASE
This  request  sends  a  purchase  message  to  the  Android  Market  
application  and  is  the  foundation  of  in
-­‐
app  billing.  You  send  this  request  when  a  user  indicates  
that  he  or  she  wants  to  purchase  an  item  in  your  application.  Android  Mar
ket  then  handles  the  
financial  transaction  by  displaying  the  checkout  user  interface.
 
22.

GET_PURCHASE_INFORMATION
This  request  retrieves  the  details  of  a  purchase  state  change.  
A  purchase  state  change  can  occur  when  a  purchase  request  is  billed  successfully  or
 
when  a  
user  cancels  a  transaction  during  checkout.  It  can  also  occur  when  a  previous  purchase  is  
refunded.  Android  Market  notifies  your  application  when  a  purchase  changes  state,  so  you  only  
need  to  send  this  request  when  there  is  transaction  information  
to  retrieve.
 
23.

CONFIRM_NOTIFICATIONS
This  request  acknowledges  that  your  application  received  the  
details  of  a  purchase  state  change.  That  is,  this  message  confirms  that  you  sent  a  
GET_PURCHASE_INFORMATION
 
request  for  a  given  notification  and  that  you  receive
d  the  
purchase  information  for  the  notification.
 
24.

RESTORE_TRANSACTIONS
This  request  retrieves  a  user

s  transaction  status  for  managed  
purchases  (see  
Choosing  a  Purchase  Type
 
for  more  information).  You  should  send  this  message  
only  when  you  need  to  retrieve  a  user

s  transaction  status,  which  is  usually  only  when  your  
application  is  reinstalled  or  installed  for  the  first  time  on  a  device.
 
Every  in
-­‐
app  billing  request  generates  a  synchronous  response.  The  response  is  a  
Bundle
 
and  can  
include  one  or  more  of  the  following  keys:
 


RESPONSE_CODE
This  key  provides  status  i
nformation  and  error  information  about  a  request.
 


PURCHASE_INTENT
This  key  provides  a  
PendingIntent
,  which  you  use  to  launch  the  
checkout  activity.
 


REQUEST_ID
This  key  prov
ides  you  with  a  request  identifier,  which  you  can  use  to  match  
asynchronous  responses  with  requests.
 
Some  of  these  keys  are  not  relevant  to  certain  types  of  requests.  Table  3  shows  which  keys  are  
returned  for  each  request  type.
 
Table  3.
 
Description  of  Bund
le  keys  that  are  returned  with  each  in
-­‐
app  billing  request  type.
 
Request Type

Keys Returned

Possible Response Codes

CHECK_BILLING_S
UPPORTED

RESPONSE_CODE

RESULT_OK
,
RESULT_BILLING_UNAVAILABLE
,
RESULT_ERROR
,
RESULT_DEVELOPER_ERROR

REQUEST_PURCHAS
E

RESPONSE_CODE
,
PURCHASE_INTENT
,
REQUEST_ID

RESULT_OK
,
RESULT_ERROR
,
RESULT_DEVELOPER_ERROR

GET_PURCHASE_IN
FORMATION

RESPONSE_CODE
,
REQUEST_ID

RESULT_OK
,
RESULT_ERROR
,
RESULT_DEVELOPER_ERROR

CONFIRM_NOTIFIC
ATIONS

RESPONSE_CODE
,
REQUEST_ID

RESULT_OK
,
RESUL
T_ERROR
,
RESULT_DEVELOPER_ERROR

RESTORE_TRANSAC
TIONS

RESPONSE_CODE
,
REQUEST_ID

RESULT_OK
,
RESULT_ERROR
,
RESULT_DEVELOPER_ERROR


In
-­‐
app  Billing  Broadcast  Intents
 
The  following  section  describes  the  in
-­‐
app  billing  broadcast  intents  that  are  sent  by  the  Android  
Market  application.  These  broadcast  intents  inform  your  application  about  in
-­‐
app  billing  actions  that  
have  occurred.  Your  application  must  implement  a  
BroadcastReceiver
 
to  receive  these  broadcast  
intents,  such  as  the  
BillingReceiver
 
that

s  shown  in  the  in
-­‐
app  billing  
sample  application
.
 
com.android.vending.billing.RESPONSE_CODE
 
This  broadcast  intent  contains  an  Android  Market  response  code,  and  is  sent  after  you  make  an  in
-­‐
app  
billing  request.  A  server  response
 
code  can  indicate  that  a  billing  request  was  successfully  sent  to  
Android  Market  or  it  can  indicate  that  some  error  occurred  during  a  billing  request.  This  intent  is  not  
used  to  report  any  purchase  state  changes  (such  as  refund  or  purchase  information).  F
or  more  
information  about  the  response  codes  that  are  sent  with  this  response,  see  
Android  Market  Response  
Codes  for  In
-­‐
app  Billing
.  The  sample  application  assigns  this  broadcast  intent  to  a  constant  named  
ACTION_RESPONSE_CODE
.
 
Extras
 


request_id

a  
long
 
rep
resenting  a  request  ID.  A  request  ID  identifies  a  specific  billing  
request  and  is  returned  by  Android  Market  at  the  time  a  request  is  made.
 


response_code

an  
int
 
representing  the  Android  Market  server  response  code.
 
 
com.android.vending.billing.IN_APP_NOTIFY
 
This  response  indicates  that  a  purchase  has  changed  state,  which  means  a  purchase  succeeded,  was  
canceled,  or  was  refunded.  This  response  contains  one  or  more  notification  IDs.  Each  notification  ID  
corresponds  to  a
 
specific  server
-­‐
side  message,  and  each  messages  contains  information  about  one  or  
more  transactions.  After  your  application  receives  an  
IN_APP_NOTIFY
 
broadcast  intent,  you  send  a  
GET_PURCHASE_INFORMATION
 
request  with  the  notification  IDs  to  retrieve  the  m
essage  details.  
The  sample  application  assigns  this  broadcast  intent  to  a  constant  named  
ACTION_NOTIFY
.
 
Extras
 


notification_id

a  
String
 
representing  the  notification  ID  for  a  given  purchase  state  
change.  Android  Market  notifies  you  when  there  is  a  purchase  state  change  and  the  
notification  includes  a  unique  notification  ID.  To  get  the  details  of  the  purchase  state  change,  
you  send  the  not
ification  ID  with  the  
GET_PURCHASE_INFORMATION
 
request.
 
 
com.android.vending.billing.PURCHASE_STATE_CHANGED
 
This  broadcast  intent  contains  detailed  information  about  one  or  more  transactions.  The  transaction  
information  is  contained  in  a  JSON  string.  The  J
SON  string  is  signed  and  the  signature  is  sent  to  your  
application  along  with  the  JSON  string  (unencrypted).  To  help  ensure  the  security  of  your  in
-­‐
app  billing  
messages,  your  application  can  verify  the  signature  of  this  JSON  string.  The  sample  application  
assigns  
this  broadcast  intent  to  a  constant  named  
ACTION_PURCHASE_STATE_CHANGED
.
 
Extras
 


inapp_signed_data

a  
String
 
representing  the  signed  JSON  string.
 


inapp_signature

a  
String
 
representing  the  signature.
 
Note:
 
Your  application  should  map  the  broadcast  int
ents  and  extras  to  constants  that  are  unique  to  
your  application.  See  the  
Consts.java
 
file  in  the  sample  application  to  see  how  this  is  done.
 
The  fields  in  the  JSON  string  are  described  in  the  following  table  (see  table  4):
 
Table  4.
 
Description  of  JSON  fie
lds  that  are  returned  with  a  
PURCHASE_STATE_CHANGED
 
intent.
 
Field

Description

nonce

A number used once. Your application generates the nonce and
sends it with the
GET_PURCHASE_INFORMATION

request. Android
Market sends the nonce back as part of the JSON string so you
can verify the integrity of the message.

notificationId

A unique identifier that is sent with an
IN_APP_NOTIFY

broadcast
intent. Each
notificationId

corresponds to a specify message
that is waiting to be retrieved on the Android Market server. Your
application sends back the
notificationId

with the
GET_PURCHASE_INFORMATION

message so Android Market can
determine which messages you are retrieving.

ord
erId

A unique order identifier for the transaction. This corresponds to
the Google Checkout Order ID.

packageName

The application package from which the purchase originated.

productId

The item

s product identifier. Every item has a product ID, which
you
must specify in the application

s product list on the Android
Market publisher site.

purchaseTime

The time the product was purchased, in milliseconds since the
epoch (Jan 1, 1970).

purchaseState

The purchase state of the order. Possible values are 0
(pur
chased), 1 (canceled), or 2 (refunded).

developerPayload

A developer
-
specified string that contains supplemental
information about an order. You can specify a value for this field
when you make a
REQUEST_PURCHASE

request.