初步实现iap
This commit is contained in:
parent
d41253352e
commit
f28703244d
|
@ -11,6 +11,8 @@ npm-debug.*
|
|||
web-build/
|
||||
test.jsx
|
||||
example.jsx
|
||||
ios
|
||||
android
|
||||
|
||||
|
||||
# macOS
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import React, { useState, createContext, useContext, useEffect } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import Purchases, { LOG_LEVEL } from "react-native-purchases";
|
||||
import { AuthContext } from "../App";
|
||||
import { get } from "../utils/storeInfo";
|
||||
|
||||
const IapContext = createContext();
|
||||
|
||||
export const IapProvider = ({ children }) => {
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const [packages, setPackages] = useState([]);
|
||||
|
||||
const { state } = useContext(AuthContext);
|
||||
|
||||
useEffect(() => {
|
||||
const init = async () => {
|
||||
if (Platform.OS === "ios" && state.isSignin) {
|
||||
const account = await get("account");
|
||||
await Purchases.configure({
|
||||
apiKey: process.env.EXPO_PUBLIC_RC_APPLE_KEY,
|
||||
appUserID: account.mid.toString(),
|
||||
});
|
||||
Purchases.setLogLevel(LOG_LEVEL.DEBUG);
|
||||
await loadOfferings();
|
||||
}
|
||||
setIsReady(true);
|
||||
};
|
||||
init();
|
||||
}, [state]);
|
||||
|
||||
const loadOfferings = async () => {
|
||||
const offerings = await Purchases.getOfferings();
|
||||
if (offerings.current) {
|
||||
setPackages(offerings.current.availablePackages);
|
||||
}
|
||||
};
|
||||
|
||||
const purchasePackage = async (pack) => {
|
||||
if (Platform.OS !== "ios") return;
|
||||
try {
|
||||
await Purchases.purchasePackage(pack);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const getCustomerInformation = async () => {
|
||||
if (Platform.OS !== "ios") return;
|
||||
try {
|
||||
const customerInfo = await Purchases.getCustomerInfo();
|
||||
return customerInfo;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const value = {
|
||||
packages,
|
||||
purchasePackage,
|
||||
getCustomerInformation,
|
||||
};
|
||||
|
||||
if (!isReady) return <></>;
|
||||
|
||||
return <IapContext.Provider value={value}>{children}</IapContext.Provider>;
|
||||
};
|
||||
|
||||
export const useIap = () => useContext(IapContext);
|
|
@ -40,6 +40,7 @@
|
|||
"expo-clipboard": "~5.0.1",
|
||||
"expo-constants": "~15.4.5",
|
||||
"expo-crypto": "~12.8.1",
|
||||
"expo-dev-client": "~3.3.11",
|
||||
"expo-device": "~5.9.3",
|
||||
"expo-file-system": "~16.0.8",
|
||||
"expo-image": "~1.10.6",
|
||||
|
@ -66,6 +67,7 @@
|
|||
"react-native-pager-view": "6.2.3",
|
||||
"react-native-parsed-text": "^0.0.22",
|
||||
"react-native-picker-select": "^8.1.0",
|
||||
"react-native-purchases": "^7.27.2",
|
||||
"react-native-reanimated": "~3.6.2",
|
||||
"react-native-safe-area-context": "4.8.2",
|
||||
"react-native-screens": "~3.29.0",
|
||||
|
|
|
@ -8,6 +8,7 @@ import * as Clipboard from "expo-clipboard";
|
|||
import Toast from "react-native-toast-message";
|
||||
import MyModal from "../../components/MyModal";
|
||||
import baseRequest from "../../utils/baseRequest";
|
||||
import { useIap } from "../../context/IapProvider";
|
||||
|
||||
export default function WebWithHeader({ navigation, route }) {
|
||||
//设置页面标题
|
||||
|
@ -87,6 +88,13 @@ export default function WebWithHeader({ navigation, route }) {
|
|||
Linking.openURL(data);
|
||||
};
|
||||
|
||||
//iap
|
||||
const { packages, purchasePackage } = useIap();
|
||||
const purchase = async (product) => {
|
||||
const pack = packages.find((p) => p.identifier === product);
|
||||
await purchasePackage(pack);
|
||||
};
|
||||
|
||||
//唤起支付宝或微信
|
||||
const handleUrlRedirect = (event) => {
|
||||
const { url } = event;
|
||||
|
@ -154,14 +162,24 @@ export default function WebWithHeader({ navigation, route }) {
|
|||
userAgent="FromWebview"
|
||||
onMessage={async (event) => {
|
||||
const msg = JSON.parse(event.nativeEvent.data);
|
||||
if (msg.type === "SAVE_IMAGE") {
|
||||
saveImage(msg.data);
|
||||
} else if (msg.type === "COPY_URL") {
|
||||
copy(msg.data);
|
||||
} else if (msg.type === "NAVIGATE") {
|
||||
navigation.navigate(msg.data.page, { ...msg.data.params });
|
||||
} else if (msg.type === "OPEN_BROWSER") {
|
||||
openBrowser(msg.data);
|
||||
switch (msg.type) {
|
||||
case "SAVE_IMAGE":
|
||||
saveImage(msg.data);
|
||||
break;
|
||||
case "COPY_URL":
|
||||
copy(msg.data);
|
||||
break;
|
||||
case "NAVIGATE":
|
||||
navigation.navigate(msg.data.page, { ...msg.data.params });
|
||||
break;
|
||||
case "OPEN_BROWSER":
|
||||
openBrowser(msg.data);
|
||||
break;
|
||||
case "IAP":
|
||||
purchase(msg.data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}}
|
||||
injectedJavaScript={setCookieScript}
|
||||
|
|
|
@ -8,6 +8,7 @@ import * as Clipboard from "expo-clipboard";
|
|||
import Toast from "react-native-toast-message";
|
||||
import MyModal from "../../components/MyModal";
|
||||
import baseRequest from "../../utils/baseRequest";
|
||||
import { useIap } from "../../context/IapProvider";
|
||||
|
||||
export default function WebWithoutHeader({ navigation, route }) {
|
||||
//前往打开权限弹窗
|
||||
|
@ -80,6 +81,13 @@ export default function WebWithoutHeader({ navigation, route }) {
|
|||
Linking.openURL(data);
|
||||
};
|
||||
|
||||
//iap
|
||||
const { packages, purchasePackage } = useIap();
|
||||
const purchase = async (product) => {
|
||||
const pack = packages.find((p) => p.identifier === product);
|
||||
await purchasePackage(pack);
|
||||
};
|
||||
|
||||
//唤起支付宝或微信
|
||||
const handleUrlRedirect = (event) => {
|
||||
const { url } = event;
|
||||
|
@ -147,14 +155,24 @@ export default function WebWithoutHeader({ navigation, route }) {
|
|||
userAgent="FromWebview"
|
||||
onMessage={async (event) => {
|
||||
const msg = JSON.parse(event.nativeEvent.data);
|
||||
if (msg.type === "SAVE_IMAGE") {
|
||||
saveImage(msg.data);
|
||||
} else if (msg.type === "COPY_URL") {
|
||||
copy(msg.data);
|
||||
} else if (msg.type === "NAVIGATE") {
|
||||
navigation.navigate(msg.data.page, { ...msg.data.params });
|
||||
} else if (msg.type === "OPEN_BROWSER") {
|
||||
openBrowser(msg.data);
|
||||
switch (msg.type) {
|
||||
case "SAVE_IMAGE":
|
||||
saveImage(msg.data);
|
||||
break;
|
||||
case "COPY_URL":
|
||||
copy(msg.data);
|
||||
break;
|
||||
case "NAVIGATE":
|
||||
navigation.navigate(msg.data.page, { ...msg.data.params });
|
||||
break;
|
||||
case "OPEN_BROWSER":
|
||||
openBrowser(msg.data);
|
||||
break;
|
||||
case "IAP":
|
||||
purchase(msg.data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}}
|
||||
injectedJavaScript={setCookieScript}
|
||||
|
|
57
yarn.lock
57
yarn.lock
|
@ -2318,6 +2318,11 @@
|
|||
dependencies:
|
||||
nanoid "^3.1.23"
|
||||
|
||||
"@revenuecat/purchases-typescript-internal@10.6.2":
|
||||
version "10.6.2"
|
||||
resolved "https://registry.npmmirror.com/@revenuecat/purchases-typescript-internal/-/purchases-typescript-internal-10.6.2.tgz#718c9f6e74e5673f53a1b612f930713783c2eafe"
|
||||
integrity sha512-bWSNwhCyiiB0CGq5092PsADBeFFtAIr4jshKghY37dtPa1jpqck0ga77+BWT9jN/J4Jtq1ME/dKKg0hIuGI+LQ==
|
||||
|
||||
"@rneui/base@^4.0.0-rc.8":
|
||||
version "4.0.0-rc.8"
|
||||
resolved "https://registry.npmmirror.com/@rneui/base/-/base-4.0.0-rc.8.tgz#6fbf9b3049a9207d47c3c53b70c0f68f3627a170"
|
||||
|
@ -2755,6 +2760,16 @@ aggregate-error@^3.0.0:
|
|||
clean-stack "^2.0.0"
|
||||
indent-string "^4.0.0"
|
||||
|
||||
ajv@8.11.0:
|
||||
version "8.11.0"
|
||||
resolved "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
|
||||
integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
json-schema-traverse "^1.0.0"
|
||||
require-from-string "^2.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@^8.11.0:
|
||||
version "8.12.0"
|
||||
resolved "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1"
|
||||
|
@ -4065,6 +4080,41 @@ expo-crypto@~12.8.1:
|
|||
dependencies:
|
||||
base64-js "^1.3.0"
|
||||
|
||||
expo-dev-client@~3.3.11:
|
||||
version "3.3.11"
|
||||
resolved "https://registry.npmmirror.com/expo-dev-client/-/expo-dev-client-3.3.11.tgz#f2541ccbcfc2ba32bcea47293bc9beae4e10db60"
|
||||
integrity sha512-9nhhbfbskfmjp/tlRS5KvDpCoW0BREJBxpu2GyjKu7nDB33W8fJLL0wXgNhP+QEb93r37o3uezKmUm2kibOvTw==
|
||||
dependencies:
|
||||
expo-dev-launcher "3.6.9"
|
||||
expo-dev-menu "4.5.8"
|
||||
expo-dev-menu-interface "1.7.2"
|
||||
expo-manifests "~0.13.0"
|
||||
expo-updates-interface "~0.15.1"
|
||||
|
||||
expo-dev-launcher@3.6.9:
|
||||
version "3.6.9"
|
||||
resolved "https://registry.npmmirror.com/expo-dev-launcher/-/expo-dev-launcher-3.6.9.tgz#5e104e0533a46f3614c1691673da3351092e8d1d"
|
||||
integrity sha512-MBDMAqjCMVYt1Zv47u2dJTp4d8gCZMfM4GWAFhfQy3G6XzkUlFtewaQefAqy93FcYOv6BYdC9yZOLOb06tqTfA==
|
||||
dependencies:
|
||||
ajv "8.11.0"
|
||||
expo-dev-menu "4.5.8"
|
||||
expo-manifests "~0.13.0"
|
||||
resolve-from "^5.0.0"
|
||||
semver "^7.5.3"
|
||||
|
||||
expo-dev-menu-interface@1.7.2:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.npmmirror.com/expo-dev-menu-interface/-/expo-dev-menu-interface-1.7.2.tgz#772fb97c6b0a44c27965cdfcfa078f316b0930ca"
|
||||
integrity sha512-V/geSB9rW0IPTR+d7E5CcvkV0uVUCE7SMHZqE/J0/dH06Wo8AahB16fimXeh5/hTL2Qztq8CQ41xpFUBoA9TEw==
|
||||
|
||||
expo-dev-menu@4.5.8:
|
||||
version "4.5.8"
|
||||
resolved "https://registry.npmmirror.com/expo-dev-menu/-/expo-dev-menu-4.5.8.tgz#21940385124c7d2745066bbcb42185ebd35f66bc"
|
||||
integrity sha512-GXfI0CmYlqjOqyFjtplXO9PSoJQoy89+50lbUSNZykDsGyvzCPzl4txdQcdHHSglKYr7lWV7aeMVeehuSct60w==
|
||||
dependencies:
|
||||
expo-dev-menu-interface "1.7.2"
|
||||
semver "^7.5.3"
|
||||
|
||||
expo-device@~5.9.3:
|
||||
version "5.9.3"
|
||||
resolved "https://registry.npmmirror.com/expo-device/-/expo-device-5.9.3.tgz#0ad61da681424aa682fa03001d0344394c01f8a1"
|
||||
|
@ -6587,6 +6637,13 @@ react-native-picker-select@^8.1.0:
|
|||
"@react-native-picker/picker" "^1.8.3"
|
||||
lodash.isequal "^4.5.0"
|
||||
|
||||
react-native-purchases@^7.27.2:
|
||||
version "7.27.2"
|
||||
resolved "https://registry.npmmirror.com/react-native-purchases/-/react-native-purchases-7.27.2.tgz#435eecb86db412e66c81a9cd0887a726a17b8135"
|
||||
integrity sha512-sLO85vTehwS4rlBJRmBYersIuNjmcjRJKvd5YY6y5xBVkw80LRJDmp7NTEfN9Dzp36XxnGb8KYcKOz1ZkubCXg==
|
||||
dependencies:
|
||||
"@revenuecat/purchases-typescript-internal" "10.6.2"
|
||||
|
||||
react-native-ratings@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.npmmirror.com/react-native-ratings/-/react-native-ratings-8.1.0.tgz#3fa9ad29128dc3a88e59518ba151e61c59dd0647"
|
||||
|
|
Loading…
Reference in New Issue