정기 결제를 개발하며 IOS 구매 내역 확인을 해야 합니다.
구성
JAVA 8
Spring boot
Maven
https://developer.apple.com/documentation/appstoreserverapi/get_transaction_history_v1
코드 먼저 작성 하고 설명하겠습니다.
pom.xml
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
service
Map<String, Object> headers = new HashMap<>();
headers.put("alg", "ES256");
headers.put("kid", "TTP2RC247M");
headers.put("typ", "JWT");
Date issuedAt = Date.from(Instant.now());
Date expiredAt = Date.from(Instant.now().plus(Duration.ofMinutes(10L)));
// 키파일
PrivateKey privateKey = getPrivateKey("key/AuthKey_TTP2RC247M.p8", "EC");
String jws = Jwts.builder()
.setHeader(headers)
.setIssuer("발급자키")
.setAudience("appstoreconnect-v1")
.setExpiration(expiredAt)
.setIssuedAt(issuedAt)
.claim("bid", "패키지명")
.signWith(privateKey, SignatureAlgorithm.ES256)
.compact();
Map<String, Object> returnList = new HashMap<>();
URL url = new URL(
"https://api.storekit.itunes.apple.com/inApps/v1/history/고객구매번호?productId=상품번호&sort=DESCENDING"
);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Bearer " + jws);
conn.setRequestProperty("Content-type", "application/json");
conn.setRequestMethod("GET");
try(BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String output;
StringBuffer sb = new StringBuffer();
while ((output = in.readLine()) != null) {
sb.append(output).append("\n");
}
if (!sb.equals("")) {
returnList = new ObjectMapper().readValue(sb.toString(), new TypeReference<Map<String, Object>>(){});
}
}
List<String> signedTransactions = new ObjectMapper().convertValue(returnList.get("signedTransactions"), new TypeReference<List<String>>() {});
for(String st : signedTransactions){
String[] check = st.split("\\.");
Base64.Decoder decoder = Base64.getDecoder();
String payload = new String(decoder.decode(check[1]));
log.info("payload :: "+payload);
}
url 은 운영, 개발(샌드박스) 이 있습니다.
저는 운영으로 진행하였습니다.
sort DESCENDING 진행 하였습니다.
JWT헤더 생성 참조
public PrivateKey getPrivateKey(String filename, String algorithm) throws IOException {
ClassPathResource resource = new ClassPathResource(filename);
String content;
InputStream inputStream = resource.getInputStream();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream) )) {
content = reader.lines().collect(Collectors.joining("\n"));
}
try {
String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
KeyFactory kf = KeyFactory.getInstance(algorithm);
return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Java did not support the algorithm:" + algorithm, e);
} catch (InvalidKeySpecException e) {
throw new RuntimeException("Invalid key format");
}
}
위와 같이 하면 나오는 로그 json
{
"transactionId":"고객주문번호",
"originalTransactionId":"고객주문번호",
"webOrderLineItemId":"주문품목ID",
"bundleId":"패키지명",
"productId":"상품명",
"subscriptionGroupIdentifier":"21419068",
"purchaseDate":1714782833000,
"originalPurchaseDate":1714782834000,
"expiresDate":1717461233000,
"quantity":1,
"type":"Auto-Renewable Subscription",
"inAppOwnershipType":"PURCHASED",
"signedDate":1718589613537, // 결제 날자
"offerType":1,
"environment":"Production",
"transactionReason":"PURCHASE",
"storefront":"KOR",
"storefrontId":"매장아이디",
"price":0,
"currency":"KRW",
"offerDiscountType":"FREE_TRIAL" // 무료체험
}
inAppOwnershipType : 구매 갱신 확인
expiresDate : 만료 날짜
signedDate : 결제 날짜
위 데이터로 결제 확인 합니다.
'공부 > JAVA' 카테고리의 다른 글
솔리드원칙 객체지향(OOP) 5원칙 (0) | 2024.05.24 |
---|---|
JAVA 인앱 결제 ( 안드로이드 구글 구매 확정 호출 ) (0) | 2024.04.19 |
JAVA 문자열 뒤집기 (0) | 2024.03.04 |
String 기능 모음 (0) | 2024.03.04 |
Java AES-256 양방향 암호화 (0) | 2024.02.16 |