- use permission에 com.android.vending.BILLNG을추가해준다.
핸들러
public Handler billingHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
//스토어와 연결
case Common.HANDLER_BILLING_INIT://1
initBilling();
break;
// 연결된 상태에서 구독 상품 가저오기
case Common.HANDLER_BILLING_GET_CONTENTS://2
getContentsList();
break;
//가저온 구독 상품을 화면에 보여주기
case Common.HANDLER_BILLING_SHOW_PURCHASE:
showBilling(userSkuDetails);
break;
//스토어 앱캐시로 체크(첫번째 체크 방법)
case Common.HANDLER_BILLING_CHECK_PERCHASE:
checkPurchaseAppCache();
break;
//스토어와 통신한뒤 체크(두번째 체크 방법)
case Common.HANDLER_BILLING_HISTORY_PURCHASE:
checkPurchaseHttpConection();
break;
//통신 실패시 처리
case Common.HANDLER_BILLING_CONNECTION_FAIL:
unstableServer();
break;
}
}
};
public static void checkPurchaseAppCache(
Context context
,String itemID
,CheckPurchaseCallback callback)
{
BillingClient cBillingClient = BillingClient.newBuilder(context)
.enablePendingPurchases()
.setListener((BillingResult billingResult, @Nullable List<Purchase> purchases)->{
})
.build();
cBillingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
//connection success
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
//check query
Purchase.PurchasesResult purchasesResult = cBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
List<Purchase> list = purchasesResult.getPurchasesList();
//앱스토어에서 정기결제 구독한 사람
if (list.size() > 0 ){
//제품이 하나라서 한개만 처리
Purchase purchase = list.get(0);
Gson gson = new Gson();
BillingStateVO bsVO = gson.fromJson(purchase.getOriginalJson(), BillingStateVO.class);
boolean isPerchase = false;
isPerchase = itemID.equals(bsVO.getPackageName())&&itemID.equals(bsVO.getProductId());
// 정기 구독한 사람
if (isPerchase){
//시간비교
long diff = DateUtils.currentTime() - bsVO.getPurchaseTime();
int diffDays = (int)(diff/(24*60*60*1000));
switch (bsVO.getPurchaseState()){
//구독중 ...
case LifeInAppConfig.PURCHASE_STATE_PURCHASED:
callback.onSubscribe(bsVO);
break;
// 구독이 끝나도 30일간 사용 가능
case LifeInAppConfig.PURCHASE_STATE_CANCELED:
//30일 지나감
if (diffDays>30){
callback.onSubscribeEND(bsVO);
} else {
callback.onSubscribe(bsVO);
}
break;
// 결제 수단문제로 구매 보류가 이뤄졌을때 ...
case LifeInAppConfig.PURCHASE_STATE_PENDING:
callback.onSubscribePending();
break;
}
}
// 정기구독 구입한적이 없는 사람
else {
callback.onNotPurchased("auto Renewing NOT YET");
}
}
//앱스토어에서 정기결제 한번도 한적 없는 사람
else {
callback.onNotPurchased(" auto renew nothing ");
}
}
//connection fail
else{
callback.onUnstableServer();
}
}
@Override
public void onBillingServiceDisconnected() {
}
});
}
purchase state : 중요한 녀석이다. 결제상태를 확인할 수 있다.
0 : 결제상태
1 : 취소상태
2 : 결제 보류 상태
사용
private void checkInAppbilling(){
LifeInAppBilling.checkPurchaseAppCache(
this
,AppConfig.BILLING_ITEM
,new CheckPurchaseCallback() {
@Override
public void onSubscribe(BillingStateVO bsVO) {
bsVO.printVO();
if (!bsVO.isAutoRenewing()){
//정책에 따라 자동갱신안한경우 자동갱신하도록 유도
}
}
@Override
public void onSubscribePending() {
//보류
}
@Override
public void onSubscribeEND(BillingStateVO bsVO) {
bsVO.printVO();
}
@Override
public void onNotPurchased(String msg) {
}
@Override
public void onUnstableServer() {
}
});
}
- interface callback을 수정해 원하는 콜백으로 구현하면 됩니다.
BillingStateVO
// 상태조회시 넘어오는 값들.
public class BillingStateVO {
private String orderId;
private String packageName;
private String productId;
private long purchaseTime;//long
private String purchaseState;//int
private String purchaseToken;
private boolean autoRenewing;//boolean
private boolean acknowledged;//boolean
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String pakageName) {
this.packageName = pakageName;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public long getPurchaseTime() {
return purchaseTime;
}
public void setPurchaseTime(long purchaseTime) {
this.purchaseTime = purchaseTime;
}
public String getPurchaseState() {
return purchaseState;
}
public void setPurchaseState(String purchaseState) {
this.purchaseState = purchaseState;
}
public String getPurchaseToken() {
return purchaseToken;
}
public void setPurchaseToken(String purchaseToken) {
this.purchaseToken = purchaseToken;
}
public boolean isAutoRenewing() {
return autoRenewing;
}
public void setAutoRenewing(boolean autoRenewing) {
this.autoRenewing = autoRenewing;
}
public boolean isAcknowledged() {
return acknowledged;
}
public void setAcknowledged(boolean acknowledged) {
this.acknowledged = acknowledged;
}
public void printVO(){
L.i("\n## orderId : "+orderId +
"\n pakageName : "+packageName +
"\n productId : "+productId +
"\n purchaseTime : "+purchaseTime +
"\n purchaseState : "+purchaseState +
"\n purchaseToken : "+purchaseToken +
"\n autoRenewing : "+autoRenewing +
"\n acknowledged : "+acknowledged +"\n"
);
}
}
알파테스트
- 앱버전 -> 관리
-새 목록 만들기
- 테스트 참여 URL 복사한뒤 구글아이디가 로그인된 브라우저(휴대폰)에서 해당 url로 이동
- 테스트 참여 시작 클릭!(
-몇분뒤 테스터로 등록되고 플레이 스토어 들어가보면 [ 앱이름 (베타,알파) ]로 이름이 바뀌어있다, 테스트 앱 등록 완료
- 결제 테스트 진행!
테스트
여기다 이메일 추가하면 15분 정도뒤 테스터로 등록되 실제 결제 하듯이 결제할수있다.
일회성 제품 및 정기 결제의 구매 흐름은 비슷하지만, 정기 결제에는 정기 결제 갱신의 성공 또는 거부와 같은 추가 시나리오가 있습니다. 두 가지 상황 모두에서 애플리케이션을 테스트하는 데 도움이 되도록 '테스트 도구, 항상 승인' 및 '테스트 도구, 항상 거부' 결제 수단을 사용할 수 있습니다. 성공적인 정기 결제 시나리오 이상의 시나리오를 테스트하려면 이러한 결제 수단을 사용하세요.
테스트 정기 결제 갱신
테스트 정기 결제는 테스트를 돕기 위해 일반적인 경우보다 더 빨리 갱신됩니다. 다음 표에는 기간이 다양한 정기 결제의 테스트 갱신 시간이 나와 있습니다.
참고:이러한 시간은 대략적인 것으로, 이벤트의 정확한 시간에는 약간의 변동이 있을 수 있습니다. 이러한 변동을 보완하려면 각 정기 결제 만료일 이후 API를 호출하여 현재 상태를 확인하세요.