@@ -649,7 +649,7 @@ export const finishTransaction = (
649649 } else if (
650650 purchase . userIdAmazon ||
651651 ( ! purchase . isAcknowledgedAndroid &&
652- purchase . purchaseStateAndroid === PurchaseStateAndroid . PURCHASED )
652+ purchase . purchaseStateAndroid === PurchaseStateAndroid . PURCHASED )
653653 ) {
654654 return myRNIapModule . acknowledgePurchase (
655655 purchase . purchaseToken ,
@@ -768,6 +768,47 @@ export const buyPromotedProductIOS = (): Promise<void> =>
768768 android : async ( ) => Promise . resolve ( ) ,
769769 } ) ( ) ;
770770
771+ const fetchJsonOrThrow = async ( url : string , receiptBody : Record < string , unknown > ,
772+ ) : Promise < Apple . ReceiptValidationResponse | false > => {
773+ const response = await fetch ( url , {
774+ method : 'POST' ,
775+ headers : new Headers ( {
776+ Accept : 'application/json' ,
777+ 'Content-Type' : 'application/json' ,
778+ } ) ,
779+ body : JSON . stringify ( receiptBody ) ,
780+ } ) ;
781+
782+ if ( ! response . ok ) {
783+ throw Object . assign ( new Error ( response . statusText ) , {
784+ statusCode : response . status ,
785+ } ) ;
786+ }
787+
788+ return response . json ( ) ;
789+ } ;
790+
791+ const requestAgnosticReceiptValidationIos = async ( receiptBody : Record < string , unknown > ,
792+ ) : Promise < Apple . ReceiptValidationResponse | false > => {
793+ const response = await fetchJsonOrThrow (
794+ 'https://buy.itunes.apple.com/verifyReceipt' ,
795+ receiptBody ,
796+ ) ;
797+
798+ // Best practice is to check for test receipt and check sandbox instead
799+ // https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
800+ if ( response && response . status === Apple . ReceiptValidationStatus . TEST_RECEIPT ) {
801+ const response = await fetchJsonOrThrow (
802+ 'https://sandbox.itunes.apple.com/verifyReceipt' ,
803+ receiptBody ,
804+ ) ;
805+
806+ return response ;
807+ }
808+
809+ return response ;
810+ } ;
811+
771812/**
772813 * Buy products or subscriptions with offers (iOS only)
773814 *
@@ -807,26 +848,20 @@ export const validateReceiptIos = async (
807848 receiptBody : Record < string , unknown > ,
808849 isTest ?: boolean ,
809850) : Promise < Apple . ReceiptValidationResponse | false > => {
851+ if ( isTest == null ) {
852+ return await requestAgnosticReceiptValidationIos ( receiptBody ) ;
853+ }
854+
810855 const url = isTest
811856 ? 'https://sandbox.itunes.apple.com/verifyReceipt'
812857 : 'https://buy.itunes.apple.com/verifyReceipt' ;
813858
814- const response = await fetch ( url , {
815- method : 'POST' ,
816- headers : new Headers ( {
817- Accept : 'application/json' ,
818- 'Content-Type' : 'application/json' ,
819- } ) ,
820- body : JSON . stringify ( receiptBody ) ,
821- } ) ;
822-
823- if ( ! response . ok ) {
824- throw Object . assign ( new Error ( response . statusText ) , {
825- statusCode : response . status ,
826- } ) ;
827- }
859+ const response = await fetchJsonOrThrow (
860+ url ,
861+ receiptBody ,
862+ ) ;
828863
829- return response . json ( ) ;
864+ return response ;
830865} ;
831866
832867/**
0 commit comments